К содержимому

С ^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}');
}
)