Flutter 集成与显式容器所有权。
ProviderScope 可以自己持有容器,也可以接收外部容器。Consumer 系列接口让 WidgetRef 的访问方式与 Riverpod 风格代码保持兼容。
ProviderScope 所有权
容器所有权会改变 dispose 的责任归属。
内部容器
ProviderScope(child: ...) 会自动释放
外部容器
ProviderScope(container: c, ...) 需要调用方手动执行 c.dispose()
非受控作用域
UncontrolledProviderScope 永远不会释放容器
常见误区
在 widget 测试中,记得释放外部注入的 ProviderContainer,以免留下悬挂计时器。
Consumer 变体
所有选项都会暴露 WidgetRef;按 widget 风格和本地状态需求选择即可。
应用根目录
各自适用场景
Consumer:适合小范围响应式区域的局部构建块。
ConsumerWidget:带 build(context, ref) 的无状态组件。
ConsumerStatefulWidget:在 ConsumerState 内持有 ref 的有状态组件。
示例:ConsumerStatefulWidget
当你同时需要 WidgetRef 和本地可变 UI 状态时,使用 ConsumerState。
class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key});
@override
ConsumerState<HomePage> createState() => _HomePageState();
}
class _HomePageState extends ConsumerState<HomePage> {
bool expanded = false;
@override
Widget build(BuildContext context) {
final user = ref.watch(currentUser);
return Column(
children: [
Text('$user'),
Switch(
value: expanded,
onChanged: (v) => setState(() => expanded = v),
),
],
);
}
}
Consumer 的内部会把重建调度到 post-frame,从而减少 build 期间调用 setState 的问题。
WidgetRef.watch 只用于那些应该触发重建的值。
把副作用放在 build 之外,改用回调以及 invoke / refresh 方法。