[読書会]Riverpod.dev/docs 翻訳及び補足(Migration guides ^0.14.0 から ^1.0.0 へ)

Riverpod.dev/docs(開始URL: https://riverpod.dev/docs/introduction/why_riverpod )には日本語訳ページ(/ja)も部分的には既にあるのですが、その部分はそのまま参照して、その他の英語訳のままのページについては自力で翻訳および解説を補足してみました。まだ工事中ですが最終的に満足ができたら上記サイトの翻訳ページに献上できないかな等という目標もあります。

本ブログの(上記Riverpod.dev/docsの)翻訳および解説の目次頁(構成上のトップページ)は次のURLになります。

本頁は、上記のうちの、「Migration guides / ^0.14.0 to ^1.0.0」の章の翻訳および解説頁になります。

Migration guides

移行ガイド

^0.14.0 から ^1.0.0 へ

長い待ち時間の後、ついに Riverpod の最初の安定バージョンがリリースされました ??

変更の完全なリストを確認するには、変更ログを参照してください。
このページでは、既存の Riverpod アプリケーションをバージョン 0.14.x からバージョン 1.0.0 に移行する方法に焦点を当てます。

自動アップグレードツールの利用

さまざまな変更点を説明する前に、Riverpod にはプロジェクトを自動的に移行するためのコマンドライン ツールが付属していることに注目してください。

コマンドライン

移行ツールをインストールするには、次のコマンドを実行します。

Dart
dart pub global activate riverpod_cli

これで、以下を実行できるはずです。

Dart
riverpod --help

コマンドラインがインストールされたので、使用を開始できます。

1.まず、ターミナルで移行するプロジェクトを開きます。

2.自分自身で、Riverpod をアップグレードはしないでください。
  移行ツールが Riverpod のバージョンを自動的にアップグレードします。

注意)
Riverpod をアップグレードしないことが重要です。
バージョン 1.0.0 がすでにインストールされている場合、ツールは正しく実行されません。そのため、ツールを起動する前に、古いバージョンが適切に使用されていることを確認して下さい。

3.プロジェクトにエラーが含まれていないことを確認して下さい。

4.次のコマンドを実行して下さい。

Dart
riverpod migrate

ツールはプロジェクトを分析し、変更を提案します。たとえば、次のような表示がされます。

Dart
-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 を使用してプロジェクトを自動的にアップグレードする方法を確認したので、必要な変更を詳しく見てみましょう。

構文の統一

Riverpodのバージョン1.0.0では、プロバイダとやり取りするための構文の統一に重点を置いています。 以前のRiverpodでは、ref.watch(provider)、useProvider(provider)、watch(provider)など、プロバイダを読み込むための、似ているようで異なる構文が多数ありました。 バージョン1.0.0では、残る構文はref.watch(provider)のみです。 他は削除されました。

例としては、

1.useProviderが削除され、HookConsumerWidgetが採用されました。

(Before)
class Example extends HookWidget {
  @override
  Widget build(BuildContext context) {
    useState(...);
    int count = useProvider(counterProvider);
    ...
  }
}
(After)
class Example extends HookConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    useState(...);
    int count = ref.watch(counterProvider);
    ...
  }
}

2.ConsumerWidgetのビルドとConsumerのビルダーのプロトタイプが変更されました。

(Before)
class Example extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    int count = watch(counterProvider);
    ...
  }
}

Consumer(
  builder: (context, watch, child) {
    int count = watch(counterProvider);
    ...
  }
)
(After)
class Example extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    int count = ref.watch(counterProvider);
    ...
  }
}

Consumer(
  builder: (context, ref, child) {
    int count = ref.watch(counterProvider);
    ...
  }
)

3.context.readが削除され、ref.readが採用されました。

(Before)
class Example extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    SomeButton(
      onPressed: () => context.read(provider.notifier).doSomething(),
    );
  }
}
(After)
class Example extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    SomeButton(
      onPressed: () => ref.read(provider.notifier).doSomething(),
    );
  }
}
StateProviderの更新

StateNotifierProviderに合わせてStateProviderが更新されました。
以前はref.watch(StateProvider)を実行するとStateControllerのインスタンスが返されていました。

移行するには、いくつかの方法があります。

状態変更せず、状態取得だけであれば、
以前は ref.watch(StateProvider) が StateController のインスタンスを返していましたが、今後は StateController を介さずに、状態を直接取得できるようになりました。(変更例は以下参照)

(変更前)以前は ref.watch(StateProvider) が StateController のインスタンスを返していました。:
final provider = StateProvider<int>(...);

Consumer(
  builder: (context, ref, child) {
    StateController<int> count = ref.watch(provider);

    return Text('${count.state}');
  }
)
(変更例1)StateController を介さずに、状態を直接取得できるようになりました。:
final provider = StateProvider<int>(...);

Consumer(
  builder: (context, ref, child) {
    int count = ref.watch(provider);

    return Text('${count}');
  }
)

また、あるいは、新しい StateProvider.state を使用して古い(StateController による)動作を維持することもできます。

(変更例2)新しい StateProvider.state を使用して古い(StateController による)動作を維持することもできます。:
final provider = StateProvider<int>(...);

Consumer(
  builder: (context, ref, child) {
    StateController<int> count = ref.watch(provider.state);

    return Text('${count.state}');
  }
)

(次の記事はこちら)

コメントを残す