RiverPod FutureProvider无法触发Drawer自动重建的问题排查
问题根因
你在build方法中错误使用了ref.read获取Provider状态:ref.read只会读取调用当下的Provider状态快照,不会建立状态监听,因此当FutureProvider从加载中状态变为加载完成/报错状态时,当前Widget不会收到状态变更通知,自然不会触发重建执行when方法的data分支逻辑。只有关闭Drawer重新打开时,Widget重新执行build流程,才会读到已经加载完成的状态值,渲染出正确的分支列表。
修复方案
把获取Provider实例的代码中ref.read替换为ref.watch即可:
@override Widget build(BuildContext context, WidgetRef ref) { // 错误写法:ref.read 不会监听状态变化 // AsyncValue<BranchRepository> provider = ref.read(repositories.branchRepositoryProvider); // 正确写法:ref.watch 会监听状态,状态更新时自动触发当前Widget重建 AsyncValue<BranchRepository> provider = ref.watch(repositories.branchRepositoryProvider); developer.log('Got branch provider.'); return Drawer( child: ListView( padding: EdgeInsets.zero, children: <Widget>[ DrawerHeader(...), ] + provider.when( data: (repository) => branchOptions(context, repository), loading: () => [const ListTile(title: Text('Reading the database...'))], error: (e, s) => [ ListTile(title: Text('Something when wrong:\n$e'))]), ), ); }
注意事项
ref.watch:用于在build流程中获取需要响应变化的状态,会在被监听的Provider状态更新时自动触发当前Widget重建,是构建响应式UI的首选APIref.read:仅用于点击事件等一次性触发的场景中获取状态,不要在build方法中使用它获取需要随状态更新的UI数据,否则会出现状态不刷新的问题。
内容的提问来源于stack exchange,提问作者Rafael Morales Gamboa
相关产品推荐
相关产品推荐

