Riverpod 的 Provider 本身不持有状态,状态存储在 ProviderContainer 中。Flutter 使用 ProviderScope 组件,它会创建并向组件树暴露一个容器;在根节点包裹应用后,组件即可读取 Provider,并通过 Consumer、ConsumerWidget、ConsumerStatefulWidget 获取 ref,调用 ref.watch 或 ref.read。ProviderScope 还支持传入 overrides 或 observers。
在纯 Dart 的命令行或服务端场景中,直接创建 ProviderContainer,使用后释放:
void main() { final container = ProviderContainer(); try { final sub = container.listen(counterProvider, (previous, next) { print('Counter changed from $previous to $next'); }); print('Counter starts at ${sub.read()}'); } finally { container.dispose(); } }
状态放在容器中的原因:关注点分离,只有 Provider 和 ref 能修改状态,UI 通常调用 notifier 方法;测试时每个测试可创建新容器获得全新状态,避免共享全局状态;覆盖与监听器在容器或作用域上配置;同一 Provider 在组件树不同部分可解析为不同状态。
测试时不要直接使用 ProviderContainer(),应使用 ProviderContainer.test(),让容器在测试结束后自动释放:
test('Counter starts at 0 and can be incremented', () { final container = ProviderContainer.test(); expect(container.read(counterProvider), 0); container.read(counterProvider.notifier).increment(); expect(container.read(counterProvider), 1); });
组件测试中,用 ProviderScope 包裹组件,必要时通过 tester.container() 获取容器。资料未提供具体的安装命令、版本要求或收费信息。