Flutter Provider跨页导航后,目标页未收状态变更通知、UI不更新
问题核心根因
本质是代码中创建了两个相互隔离的独立LogFoldersModel实例,状态变更和UI监听根本不在同一个实例上:
- Screen A中通过
Provider.of<LogFoldersModel>(context, listen: false)拿到并修改的,是A页面上层组件树注入的LogFoldersModel实例,修改后触发的通知也只会发给这个实例的绑定监听者 - Screen B在build方法内部嵌套了
ChangeNotifierProvider(create: (context) => LogFoldersModel()),这行代码会在B页面的组件树里新建一个完全独立的LogFoldersModel实例,这个实例带着默认的初始灰色值,和A页面修改的那个实例没有任何关联,自然收不到状态变更通知
之前在Screen B里放按钮能正常更新的原因,是当时按钮和修改逻辑、Consumer监听逻辑都绑定在B页面自己创建的这个本地实例上,自改自通知逻辑闭环;当把修改逻辑挪到A页之后,两边操作的不是同一个实例,自然就出现状态同步失效。
修复步骤
- 移除Screen B build方法中嵌套的那层
ChangeNotifierProvider,不要在业务页面内部重复创建同类型的全局状态实例 - 将LogFoldersModel的
ChangeNotifierProvider注入层级提升到App根组件(即MaterialApp的上层),保证从A到B的整个导航链路中,所有页面通过Provider获取的都是同一个单例LogFoldersModel - 保留Screen B中原有的
Consumer<LogFoldersModel>监听逻辑即可,这部分实现没有问题
修正后关键代码参考
移除了本地重复创建Provider的Screen B代码:
// Screen B 修正后的build方法 return Scaffold( body: Consumer<LogFoldersModel>( builder: (_, logfolder, __) { return Container( height: 47, width: 276, color: logfolder.color, child: Text( 'Box that has to change color', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 13, fontWeight: FontWeight.w200 ), ), ); }, ), );
App根组件注入全局Provider的示例:
// 根组件层级注入,保证全局拿到同一个实例 ChangeNotifierProvider( create: (context) => LogFoldersModel(), child: MaterialApp( // 路由、页面配置 ), )
内容的提问来源于stack exchange,提问作者SAM
相关产品推荐
相关产品推荐

