Dart Provider:在直接子代不可用

问题描述 投票:0回答:1
  @override
  Widget build(BuildContext context) {
    return BlocProvider<HomeBloc>(
        create: (context) {
          return HomeBloc(homeRepo: HomeRepository());
        },
        child: BlocProvider.of<HomeBloc>(context).state is HomeStateLoading
            ? CircularProgressIndicator()
            : Container());
  }

我对错误感到困惑:

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>().

我不是直接在其直接父级创建HomeBloc吗?要什么

flutter dart provider bloc
1个回答
0
投票
您正在使用传递到小部件类的context方法中的build查找父级BlocProvider。但是,就您的小部件类而言,上下文是小部件树。因此,您的BlocProvider.of正在寻找作为您[的父级的BlocProvider。如果要获取作为直接父级的提供者,则需要一个新的context对象,其中BlocProvider是小部件树中的祖先。最简单的方法是使用Builder小部件:

@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(), ), ); } 话虽如此,创建一个提供程序然后立即尊重该提供程序是非常多余的。提供者用于在小部件树的下方检索内容,通常不用于直接后代。在这种情况下,使用提供程序是过大的,实际上没有任何理由不只是让bloc成为您的类的一个字段并直接引用它。


0
投票

最简单的读取值的方法是使用静态方法Provider.of(BuildContext上下文)。

此方法将从小部件开始在小部件树中查找与传递的BuildContext相关联,它将返回最近的找到类型T的变量(如果未找到,则抛出)。

在您的情况下,它将开始从整个窗口小部件(与BuildContext相关联的地方)查找窗口小部件树。

因此您需要移动BlocProvider才能成为此小部件的祖先。

[如果由于某些原因无法实现,则可以使用Consumer,当您没有作为提供者的后代的BuildContext时,可以从提供者获取值。

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

© www.soinside.com 2019 - 2024. All rights reserved.