ChangeNotifierProvider 和 FutureProvider 是 Flutter 中 provider 包提供的两种不同的状态管理方案,它们的核心区别在于适用场景和数据加载方式。以下是详细对比和典型使用案例:
1. ChangeNotifierProvider
特点:
用于管理可变状态,通常与 ChangeNotifier 类配合使用。
当状态变化时,自动通知依赖该状态的 Widget 重建。
适合需要频繁更新的局部状态(如表单、计数器、用户交互等)。
典型使用场景:
用户点击按钮修改某个状态。
购物车商品增减、主题切换等需要即时响应的场景。
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知监听者重建
}
}
// 在 Widget 树中提供状态
ChangeNotifierProvider(
create: (context) => Counter(),
child: MaterialApp(...),
);
// 子 Widget 中使用状态
Consumer<Counter>(
builder: (context, counter, child) => Text('${counter.count}'),
);
2. FutureProvider
特点:
用于提供异步数据(如 API 请求、数据库查询等)。
在数据加载完成前,可以显示加载状态或错误处理。
数据通常只加载一次,后续需手动触发更新(如通过 refresh)。
典型使用场景:
从网络或本地存储加载初始数据(如用户配置、文章列表)。
需要处理异步操作的结果(成功/失败/加载中)。
FutureProvider<UserProfile>(
create: (context) => fetchUserProfile(), // 返回 Future<UserProfile>
initialData: UserProfile.loading(), // 可选初始数据
child: MaterialApp(...),
);
// 子 Widget 中使用
Consumer<UserProfile>(
builder: (context, profile, child) {
if (profile.isLoading) return CircularProgressIndicator();
if (profile.error != null) return Text('Error: ${profile.error}');
return Text('Username: ${profile.name}');
},
);
核心区别总结
| 特性 | ChangeNotifierProvider | FutureProvider |
|---|---|---|
| 数据类型 | 同步可变状态 | 异步一次性数据 |
| 更新机制 | 手动调用 notifyListeners
|
依赖 Future 的完成 |
| 典型场景 | 交互频繁的局部状态 | 初始数据加载(如 API 调用) |
| 重建触发条件 | 状态变化时 | Future 完成或刷新时 |
结合使用的案例
如果需要先异步加载数据,再允许用户修改,可以组合使用:
FutureProvider<Config>(
create: (context) => loadConfig(),
child: ChangeNotifierProvider<EditorState>(
create: (context) => EditorState(
config: Provider.of<Config>(context, listen: false),
),
child: App(),
),
);
关键点:
FutureProvider 先加载初始配置。
ChangeNotifierProvider 接管配置的后续修改。
通过这种组合,可以清晰分离数据加载和状态管理的职责。










网友评论