Flutter 整合與明確的 container 所有權。

ProviderScope 可以自己持有 container,也可以接收外部 container。Consumer 系列 API 讓 WidgetRef 的存取方式與 Riverpod 風格程式碼保持相容。

ProviderScope 所有權

container 所有權會改變 dispose 的責任歸屬。

內部 container

ProviderScope(child: ...) 會自動釋放

外部 container

ProviderScope(container: c, ...) 需要由呼叫端執行 c.dispose()

未受控的 scope

UncontrolledProviderScope 永遠不會釋放 container

常見誤區

在 widget test 中,記得釋放外部注入的 ProviderContainer,以避免留下待處理的 timer leak。

Consumer 變體

所有選項都會暴露 WidgetRef;依據 widget 風格與本地狀態需求選擇即可。

應用程式根目錄

各自適用時機

Consumer:適合小範圍 reactive 區域的區域性 builder 區塊。
ConsumerWidget:帶有 build(context, ref) 的 stateless widget。
ConsumerStatefulWidget:在 ConsumerState 內持有 ref 的 stateful widget。

範例: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 之外,改用 callback 以及 invoke / refresh 方法。

下一步

測試

在 unit test 與 widget test 中驗證 container 生命週期、覆寫與非同步更新。

開啟測試

API 參考

查看 ProviderScope、WidgetRef 與 container 方法的簽名。

開啟 API 參考