Skip to content
Development
Skill

/flutter-change-notifier

Use when setting up ChangeNotifier models, providing them to the widget tree, consuming state with Consumer or Provider.of, or optimizing rebuilds.

From plugin
flutter-ai-skills
63937 skills
Install
$ npx -y skills add evanca/flutter-ai-rules --skill flutter-change-notifier --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/flutter-change-notifier

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when setting up ChangeNotifier models, providing them to the widget tree, consuming state with Consumer or Provider.of, or optimizing rebuilds.

SKILL.md

flutter-change-notifier.SKILL.md
name: flutter-change-notifier
description: "Use when setting up ChangeNotifier models, providing them to the widget tree, consuming state with Consumer or Provider.of, or optimizing rebuilds."
license: MIT

Flutter ChangeNotifier Skill

This skill defines how to correctly use `ChangeNotifier` with the `provider` package for state management in Flutter.

---

1. Model

Extend `ChangeNotifier` to manage state. Keep internal state **private** and expose **unmodifiable views**. Call `notifyListeners()` on every state change.

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();
  }
}
  • Place shared state **above** the widgets that use it in the widget tree.
  • Never directly mutate widgets or call methods on them to change state — rebuild widgets with new data instead.

---

2. Providing the Model

ChangeNotifierProvider(
  create: (context) => CartModel(),
  child: MyApp(),
)
  • `ChangeNotifierProvider` **automatically disposes** of the model when it is no longer needed.
  • Use `MultiProvider` when you need to provide multiple models:
MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => CartModel()),
    ChangeNotifierProvider(create: (_) => UserModel()),
  ],
  child: MyApp(),
)

---

3. Consuming State

Consumer

Consumer<CartModel>(
  builder: (context, cart, child) => Stack(
    children: [
      if (child != null) child,
      Text('Total price: ${cart.totalPrice}'),
    ],
  ),
  child: const SomeExpensiveWidget(), // rebuilt only once
)
  • Always specify the generic type (`Consumer<CartModel>`, not `Consumer`).
  • Use the `child` parameter to pass **widgets that don't depend on the model** — they are built once and reused.
  • Place `Consumer` widgets **as deep in the widget tree as possible** to minimize the scope of rebuilds:
HumongousWidget(
  child: AnotherMonstrousWidget(
    child: Consumer<CartModel>(
      builder: (context, cart, child) {
        return Text('Total price: ${cart.totalPrice}');
      },
    ),
  ),
)

Provider.of with listen: false

Use `Provider.of<T>(context, listen: false)` when you only need to **call methods** on the model, not react to state changes:

Provider.of<CartModel>(context, listen: false).removeAll();

---

4. Optimization Rules

  • Do **not** wrap large widget subtrees in a `Consumer` if only a small part depends on the model.
  • Avoid rebuilding widgets unnecessarily — structure your widget tree and provider usage carefully.
  • Use `listen: false` in callbacks (e.g., `onPressed`) where you trigger actions but don't need rebuilds.

---

5. Testing

Write **unit tests** for your `ChangeNotifier` models to verify state changes and notifications:

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);
});

---

References

  • [Flutter Website GitHub Repository](https://github.com/flutter/website)
Read more
Ships withflutter-ai-skills

36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.

Get the whole plugin
Stats
639
Stars
66
Forks
Active
Maintenance
Shell
Language
MIT
License
3d ago
Last commit
1y ago
Created

Repo: evanca/flutter-ai-rules

Other skills on flutter-ai-skills.