关于 flutter-change-notifier
面向 Flutter 开发的 ChangeNotifier 与 provider 状态管理技能,说明模型组织、状态提供和消费方式。还包含减少不必要重建及测试模型通知的指导。
主要功能
- 01封装私有状态并提供不可变视图
- 02通过 Provider 提供模型
- 03使用 Consumer 消费状态
- 04缩小组件重建范围
- 05编写 ChangeNotifier 单元测试
适用场景
- 01在 Flutter 应用中共享模型状态
- 02减少状态更新引发的组件重建
- 03验证模型状态变化与通知
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ evanca/ flutter-ai-rules --skill flutter-change-notifier安装后在 Claude Code 中输入/flutter-change-notifier确认已加载。
详细介绍
Flutter ChangeNotifier 技能
本技能介绍如何在 Flutter 中将 ChangeNotifier 与 provider 包搭配使用,以正确管理状态。
1. 模型
扩展 ChangeNotifier 以管理状态。将内部状态设为私有,并公开不可修改的视图。每次状态发生变化时,都调用 notifyListeners()。
class CartModel extends ChangeNotifier {
final List<Item> _items = [];
UnmodifiableListView<Item> get items => UnmodifiableListView(_items);
void add(Item item) {
_items.add(item);
notifyListeners();
}
void removeAll() {
_items.clear();
notifyListeners();
}
}
- 在组件树中,将共享状态放在使用它的组件上方。
- 切勿直接修改组件或调用组件上的方法来改变状态;应使用新数据重建组件。
2. 提供模型
ChangeNotifierProvider(
create: (context) => CartModel(),
child: MyApp(),
)
- 当模型不再需要时,
ChangeNotifierProvider会自动释放它。 - 需要提供多个模型时,使用
MultiProvider:
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CartModel()),
ChangeNotifierProvider(create: (_) => UserModel()),
],
child: MyApp(),
)
3. 使用状态
Consumer
Consumer<CartModel>(
builder: (context, cart, child) => Stack(
children: [
if (child != null) child,
Text('Total price: ${cart.totalPrice}'),
],
),
child: const SomeExpensiveWidget(), // rebuilt only once
)
- 始终指定泛型类型(
Consumer<CartModel>,而不是Consumer)。 - 使用
child参数传入不依赖模型的组件——它们只会构建一次,并在之后重复使用。 - 将
Consumer组件尽可能放在组件树的深处,以尽量缩小重建范围:
HumongousWidget(
child: AnotherMonstrousWidget(
child: Consumer<CartModel>(
builder: (context, cart, child) {
return Text('Total price: ${cart.totalPrice}');
},
),
),
)
使用 listen: false 的 Provider.of
当只需要在模型上调用方法,而不需要响应状态变化时,使用 Provider.of<T>(context, listen: false):
Provider.of<CartModel>(context, listen: false).removeAll();
4. 优化规则
- 如果只有一小部分依赖模型,不要用
Consumer包裹大型组件子树。 - 谨慎组织组件树和 provider 的用法,避免不必要地重建组件。
- 在回调中(例如
onPressed)触发操作且不需要重建时,使用listen: false。
5. 测试
为 ChangeNotifier 模型编写单元测试,以验证状态变化和通知:
test('adding item updates total', () {
final cart = CartModel();
var notified = false;
cart.addListener(() => notified = true);
cart.add(Item('Book'));
expect(cart.items.length, 1);
expect(notified, isTrue);
});
参考资料
评论
支持 Markdown