Flutter使用懒加载国际化时跳转页面后热重载报错
问题原因
这个空指针报错核心是全局Cubit作用域配置错误:
- 你把提供
CurrentLocaleCubit的LocalizationContainer写在了MaterialApp的home属性里,而MaterialApp内置的Navigator是管理所有路由的父组件,home对应的引导页只是Navigator管理的第一个子路由,和后续push、pushReplacement打开的登录页、首页是平级关系。 - 平级路由之间无法互相访问对方组件树里提供的Bloc/Cubit实例。你第一次跳转时通过
BlocProvider.value手动把旧路由里的cubit传给新路由,首次构建能正常运行,但触发热重载时,Flutter会重新构建整个路由栈的组件,这时候新路由的context向上遍历找不到对应的CurrentLocaleCubit提供节点,BlocProvider.of<CurrentLocaleCubit>(context)就会返回null,触发空检查报错。 - 停留在引导页时不报错,是因为引导页本身就在
LocalizationContainer的子树内,始终能正常访问到cubit。
修复方案
按以下两点修改即可彻底解决问题:
- 上移全局Cubit到真正的根节点
把LocalizationContainer挪到MaterialApp外层,让所有路由都处于它的子树范围内,全局都能访问到CurrentLocaleCubit,修改后的main文件代码:return LocalizationContainer( child: MaterialApp( title: 'My App', theme: myTheme(context), debugShowCheckedModeBanner: false, home: PresentationContainer(), ), ); - 移除冗余的手动传值逻辑
现在CurrentLocaleCubit已经全局可用,跳转路由时不需要再手动通过BlocProvider.value传递实例,简化跳转代码:void _goToLogin(BuildContext blocContext) { Navigator.of(blocContext).pushReplacement( MaterialPageRoute( builder: (context) => LoginContainer(), ), ); }
补充优化建议
如果I18NLoadingContainer目前没有做翻译缓存,可以把翻译缓存逻辑也放到全局层,避免页面返回、热重载时重复拉取相同页面的翻译资源,减少不必要的网络请求。
内容的提问来源于stack exchange,提问作者Gustavo F.
相关产品推荐
相关产品推荐

