Dart Provider: not available at the immediate child

旧巷老猫 提交于 2020-12-15 05:01:51

问题


  @override
  Widget build(BuildContext context) {
    return BlocProvider<HomeBloc>(
        create: (context) {
          return HomeBloc(homeRepo: HomeRepository());
        },
        child: BlocProvider.of<HomeBloc>(context).state is HomeStateLoading
            ? CircularProgressIndicator()
            : Container());
  }

I am confused with the error:

BlocProvider.of() called with a context that does not contain a Bloc of type HomeBloc.
No ancestor could be found starting from the context that was passed to
BlocProvider.of<HomeBloc>().

Didn't I just create the HomeBloc at its immediate parent? What does it want?


回答1:


You are using the context passed into the build method of your widget class to look for a parent BlocProvider. However, that context is the widget tree as far as your widget class sees it. Because of this, your BlocProvider.of is looking for a BlocProvider that is a parent of your widget class. If you want to get the provider that is the immediate parent, you need a new context object in which the BlocProvider is an ancestor in the widget tree. The easiest way to do this is with a Builder widget:

@override
Widget build(BuildContext context) {
  return BlocProvider<HomeBloc>(
    create: (context) {
      return HomeBloc(homeRepo: HomeRepository());
    },
    child: Builder(
      builder: (newContext) => BlocProvider.of<HomeBloc>(newContext).state is HomeStateLoading
          ? CircularProgressIndicator()
          : Container(),
    ),
  );
}

That being said, it's pretty redundant to create a provider and then immediately reverence the provider. Providers are for retrieving stuff further down the widget tree, not typically for immediate descendants. In this case, using a provider is overkill and there isn't really any reason to not just have the bloc be a field of your class and reference it directly.




回答2:


From the documentation :

The easiest way to read a value is by using the static method Provider.of(BuildContext context).

This method will look up in the widget tree starting from the widget associated with the BuildContext passed and it will return the nearest variable of type T found (or throw if nothing is found).

In your case it starts looking up the widget tree from your whole widget (associated to the BuildContext).

So you need to move your BlocProvider to be an ancestor of this widget.

If for some reason this is not possible, you can use Consumer, which allows obtaining a value from a provider when you don't have a BuildContext that is a descendant of the said provider.

Read https://pub.dev/documentation/provider/latest/provider/Consumer-class.html



来源:https://stackoverflow.com/questions/59723597/dart-provider-not-available-at-the-immediate-child

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!