技能 编程开发 Flutter Provider状态管理指南

Flutter Provider状态管理指南

v20260418
provider
本技能详细介绍了如何在Flutter中使用`provider`包进行状态管理和依赖注入。内容涵盖了不同类型的Provider(如`ChangeNotifierProvider`、`FutureProvider`、`StreamProvider`)的使用,指导了使用`MultiProvider`进行最佳实践配置,并展示了通过`context.watch`、`Selector`等方式高效消费状态,确保应用的高可维护性和性能。
获取技能
327 次下载
概览

Provider Skill

This skill defines how to correctly use the provider package in Flutter applications.


1. Provider Types

Provider Use for
Provider Exposing any immutable value
ChangeNotifierProvider Mutable state with ChangeNotifier
FutureProvider Exposing a Future result
StreamProvider Exposing a Stream
ProxyProvider / ChangeNotifierProxyProvider Objects that depend on other providers

2. Setup

MultiProvider(
  providers: [
    Provider<Something>(create: (_) => Something()),
    ChangeNotifierProvider(create: (_) => MyNotifier()),
    FutureProvider<String>(create: (_) => fetchData(), initialData: ''),
  ],
  child: MyApp(),
)
  • Use MultiProvider to group multiple providers and avoid deeply nested trees.
  • ChangeNotifierProvider automatically disposes the model when it is no longer needed.
  • Never create a provider's object from variables that can change over time — the object won't update when the variable changes. Use ProxyProvider instead.
  • If you have 150+ providers, consider mounting them over time (e.g., during a splash screen) rather than all at once to avoid StackOverflowError.

3. Consuming State

Always specify the generic type for type safety:

// Listen and rebuild on change — only valid inside build() or a Provider's update method
final count = context.watch<MyModel>().count;

// Access without listening — use in callbacks, not inside build()
context.read<MyModel>().increment();

// Listen to only part of the state
final count = context.select<MyModel, int>((m) => m.count);

Use Consumer<T> or Selector<T, R> widgets when you need fine-grained rebuilds and cannot access a descendant BuildContext:

Consumer<MyModel>(
  builder: (context, model, child) => Text('${model.count}'),
  child: const ExpensiveWidget(), // rebuilt only once
)

Selector<MyModel, int>(
  selector: (_, model) => model.count,
  builder: (_, count, __) => Text('$count'),
)

4. ProxyProvider

Use ProxyProvider or ChangeNotifierProxyProvider for objects that depend on other providers or values that can change:

MultiProvider(
  providers: [
    Provider<Auth>(create: (_) => Auth()),
    ProxyProvider<Auth, Api>(
      update: (_, auth, __) => Api(auth.token),
    ),
  ],
)

5. Rules

  • Do not access providers inside initState or constructors — use them in build, callbacks, or lifecycle methods where the widget is fully mounted.
  • You can use any object as state, not just ChangeNotifier; use Provider.value() with a StatefulWidget if needed.

6. Debugging

Implement toString or DiagnosticableTreeMixin to improve how your objects appear in Flutter DevTools:

class MyModel with DiagnosticableTreeMixin {
  final int count;
  MyModel(this.count);

  @override
  String toString() => 'MyModel(count: $count)';
}

7. Migration: ValueListenableProvider

ValueListenableProvider is deprecated. Use Provider with ValueListenableBuilder instead:

ValueListenableBuilder<int>(
  valueListenable: myValueListenable,
  builder: (context, value, _) {
    return Provider<int>.value(
      value: value,
      child: MyApp(),
    );
  },
)

References

信息
Category 编程开发
Name provider
版本 v20260418
大小 3.58KB
更新时间 2026-04-25
语言