Providerの内部では、nestedというパッケージが使われています。
nestedパッケージを理解して、MultiProviderが実際にはproviderのネストを簡単に記述できるようにしているだけであることを確認します。
MultiProviderでは実質的には表記順にもとづいて親子関係が作られているので、順番が問題になることがあります。
nestedパッケージ
https://pub.dev/packages/nested の通り、
MyWidget(
child: AnotherWidget(
child: Again(
child: AndAgain(
child: Leaf(),
)
)
)
)
を、MyWidget~AndAgainをすべてSingleChildStatelessWidget
もしくはSingleChildStatefulWidget
を継承させて書き換えることで以下のように書き換えられる。
Nested(
children: [
MyWidget(),
AnotherWidget(),
Again(),
AndAgain(),
],
child: Leaf(),
)
MyWidgetの書き換え例は以下。
SingleChildStatelessWidget
は、build
のかわりにbuildWithChild
をoverrideさせる。(buildをoverrideしてはいけない)
class MyWidget extends StatelessWidget {
MyWidget({Key key, this.child}): super(key: key);
final Widget child;
@override
Widget build(BuildContext context) {
return SomethingWidget(child: child);
}
}
class MyWidget extends SingleChildStatelessWidget {
MyWidget({Key key, Widget child}): super(key: key, child: child);
@override
Widget buildWithChild(BuildContext context, Widget child) {
return SomethingWidget(child: child);
}
}
MultiProvider
Providerの内部では、すべてのProviderの祖先であるInheritedWidget
がSingleChildStatelessWidget
を継承し、MultiProvider
がNested
を継承している。
そうすることで、
Provider<Something>(
create: (_) => Something(),
child: Provider<SomethingElse>(
create: (_) => SomethingElse(),
child: Provider<AnotherThing>(
create: (_) => AnotherThing(),
child: someWidget,
),
),
)
を、
MultiProvider(
providers: [
Provider<Something>(create: (_) => Something()),
Provider<SomethingElse>(create: (_) => SomethingElse()),
Provider<AnotherThing>(create: (_) => AnotherThing()),
],
child: someWidget,
)
のように書けるようにしている。(最初の例と同じように)