问题
@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