2020/12/19 :Consumer classの訳

Obtains Provider<T> from its ancestors and passes its value to builder.

先祖ウィジェットからProvider<T>を取得し、builderにその値を渡す。

そのまま訳しているが、取得するのはT型のはず。

Consumerウィジェットはファンシーな挙動はありません。新しいウィジェットの中でただProvider.ofメソッドを呼び出すだけです。そしてbuildメソッドの返り値としてbuilderフィールド(にセットされたコールバック)の返り値を返します。

builderはnullではいけません。そしてbuilderは何回も呼び出されます。(Provider.ofで取得した値が変化する度に)

Consumerウィジェットには二つの主な目的があります。

Providerの子孫ウィジェットのBuildContextを用いることができない場合でもProviderが提供する値(value)を取得できます。それゆえProvider.ofは使えません。

このシナリオは、以下のようなコードで発生します。

@override
Widget build(BuildContext context) {
  return ChangeNotifierProvider(
    create: (_) => Foo(),
    child: Text(Provider.of<Foo>(context).value),
  );
}

5行目のcontextは2行目の引数のcontextなので、5行目の

Provider.of<Foo>(context)

は、このbuildメソッドを持つウィジェットの祖先ウィジェットからFoo型を探す。実際やりたいのは、3行目のChangeNotifierProviderが提供するFoo()を取得したい訳なので、意図とは違う挙動、ということになる。

このサンプルはProviderNotFoundExceptionをスローします。なぜなら、Provider.ofはProviderの祖先のBuildContextを引数に渡されて呼び出されているからです。…