Flutter Bloc已用BlocProvider.value提供却提示上下文找不到祖先实例如何解决
错误根因
你代码的核心问题是上下文变量名冲突,导致取Bloc时用了错误的上下文:
在AddCollaboratorButton的悬浮按钮点击逻辑里,MaterialPageRoute的builder回调的形参命名为context,和外层按钮所在的上下文变量名重复,此时你在builder内部调用BlocProvider.of<NavigateHomeScreenBloc>(context)用的是新路由的未挂载Bloc的上下文,自然找不到对应Bloc实例。
修复方案
只需要把MaterialPageRoute的builder形参改名,避免和外层上下文重名即可,修改后的代码如下:
FloatingActionButton( onPressed: () { // 从按钮所在的正确上下文提前取出Bloc实例 final homeBloc = BlocProvider.of<NavigateHomeScreenBloc>(context); Navigator.of(context) .push(MaterialPageRoute( // 把builder形参改名,避免和外层context冲突 builder: (routeContext) => BlocProvider.value( value: homeBloc, child: DemandeCollaboration()))) .then((value) => homeBloc.add(NavigateToDemandes())); }, child: Icon(Icons.add, color: Colors.white), ),
提前把Bloc实例从正确的上下文取出来存为变量,既避免context用错,也不用多次调用BlocProvider.of,性能更好。
额外注意事项
- 所有涉及嵌套回调、路由构建的场景,都要注意上下文变量的命名不要重复,避免误取
- 如果你的
NavigateHomeScreenBloc是整个首页生命周期内都需要使用的,也可以直接把它的提供者放到MaterialApp的上层,全局可访问,就不需要手动跨路由传递Bloc实例了
内容的提问来源于stack exchange,提问作者Dev Lulu
相关产品推荐
相关产品推荐

