С ^0.14.0 на ^1.0.0
После длительного ожидания наконец вышла первая стабильная версия 👏
Чтобы просмотреть полный список изменений, обратитесь к Changelog. В этой статье мы рассмотрим миграцию Riverpod приложения с версии 0.14.x на 1.0.0.
Использование инструмента миграции для автоматического обновления синтаксиса в вашем проекте
Перед началом разбора изменений, стоит отметить, что Riverpod имеет инструмент командной строки для автоматической миграции ваших проектов.
Установка инструмента командной строки
Для установки инструмента миграции выполните:
dart pub global activate riverpod_cli
Теперь вы можете выполнить:
riverpod --help
Использование
Когда инструмент установлен, мы можем начать использовать его.
Для начала, откройте в терминале проект, который необходимо мигрировать.
Не обновляйте Riverpod. Инструмент миграции сам обновит версию Riverpod.
осторожноВажно не обновлять Riverpod. Утилита не выполнит работу верно, если вы уже установили версию 1.0.0. Также убедитесь, что вы правильно используете старую версию, перед тем, как запустить утилиту.
Убедитесь, что проект не содержит ошибок.
Выполните:
riverpod migrate
Данный инструмент проанализирует ваш проект и предложит изменения. Например вы можете увидеть:
-Widget build(BuildContext context, ScopedReader watch) {
+Widget build(BuildContext context, Widget ref) {
- MyModel state = watch(provider);
+ MyModel state = ref.watch(provider);
}
Accept change (y = yes, n = no [default], A = yes to all, q = quit)?
Чтобы применить изменение, просто нажмите y. Чтобы отклонить изменение, нажмите n.
Изменения
Теперь, когда мы знаем как использовать CLI для автоматической миграции проекта, можно детально рассмотреть важные изменения.
Единый синтаксис
Версия 1.0.0 Riverpod сфокусирована на едином синтаксисе использования провайдеров.
Ранее Riverpod имел похожий, но все же разный синтаксис чтения провайдеров
(ref.watch(provider)
, useProvider(provider)
, watch(provider)
).
С выходом 1.0.0 версии остался только один синтаксис: ref.watch(provider)
.
Другие были исключены.
Такие как:
useProvider
убран в пользуHookConsumerWidget
.Раньше:
class Example extends HookWidget {
Widget build(BuildContext context) {
useState(...);
int count = useProvider(counterProvider);
...
}
}Теперь:
class Example extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
useState(...);
int count = ref.watch(counterProvider);
...
}
}Изменились сигнатуры метода
build
виджетаConsumerWidget
и методаbuilder
виджетаConsumer
.Раньше:
class Example extends ConsumerWidget {
Widget build(BuildContext context, ScopedReader watch) {
int count = watch(counterProvider);
...
}
}
Consumer(
builder: (context, watch, child) {
int count = watch(counterProvider);
...
}
)Теперь:
class Example extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
int count = ref.watch(counterProvider);
...
}
}
Consumer(
builder: (context, ref, child) {
int count = ref.watch(counterProvider);
...
}
)context.read
убран в пользуref.read
.Раньше:
class Example extends StatelessWidget {
Widget build(BuildContext context) {
SomeButton(
onPressed: () => context.read(provider.notifier).doSomething(),
);
}
}Теперь:
class Example extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
SomeButton(
onPressed: () => ref.read(provider.notifier).doSomething(),
);
}
}
Обновление StateProvider
StateProvider был обновлен, чтобы соответствовать StateNotifierProvider.
Раньше использование ref.watch(StateProvider)
возвращало экземпляр StateController
.
Теперь возвращается состояние StateController
.
Есть несколько вариантов миграции. Если ваш код получал состояние и не изменял его, вы можете осуществить такую замену:
final provider = StateProvider<int>(...);
Consumer(
builder: (context, ref, child) {
StateController<int> count = ref.watch(provider);
return Text('${count.state}');
}
)
на:
final provider = StateProvider<int>(...);
Consumer(
builder: (context, ref, child) {
int count = ref.watch(provider);
return Text('${count}');
}
)
Либо вы можете использовать новый синтаксис StateProvider.state
, чтобы оставить прежнее поведение.
final provider = StateProvider<int>(...);
Consumer(
builder: (context, ref, child) {
StateController<int> count = ref.watch(provider.state);
return Text('${count.state}');
}
)