state_watcher

一个简单但强大的 Flutter 应用程序响应式状态管理解决方案。

指南

应用程序的全局状态可以看作是一组独立的真实来源以及派生状态,这些状态是从它们和其他状态计算出来的。
例如,在计数器应用程序中,整个应用程序只有一个真实来源:计数器

state_watcher 中,这样的状态由 Provided 声明。

// We declare here a state which has an initial value of 0
// and it can be referenced through `refCounter`.
final refCounter = Provided((_) => 0);

实际状态存储在称为 Store 的东西中。为此,在 Flutter 中,我们可以使用 StateStore 小部件在小部件树中声明一个新的 store。

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    // The root store can be declared just above the MaterialApp
    // so that it can be accessed from anywhere in the application.
    return const StateStore(
      child: MaterialApp(
        home: MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

然后,为了显示我们计数器的值,我们需要获取 store。我们可以使用 WatcherBuilder 在任何小部件中做到这一点!

WatcherBuilder(
  builder: (BuildContext context, BuildStore store) {
    // Thanks to the WatcherBuilder, we get the store from the nearest StateStore ancestor.
    // With this store we can watch the state referenced by `refCounter`.
    // Whenever the state changes, the builder of the WatcherBuilder will be called again.
    final counter = store.watch(refCounter);
    return Text('$counter');
  },
),

现在我们需要能够更新实际状态,为此我们仍然需要一个 store。
我们可以创建另一个 WatcherBuilder 并使用 store 来更新值,但这处理 builder 小部件可能会很麻烦。
相反,我们将创建一个扩展 WatcherStatelessWidget 的专用小部件!
WatcherStatelessWidget 类似于 StatelessWidget,除了它有一个不同的 build 方法签名,我们可以在其中获取 store。

class _IncrementButton extends WatcherStatelessWidget {
  const _IncrementButton();

  @override
  Widget build(BuildContext context, BuildStore store) {
    // As with WatcherBuilder we can get the store.
    return FloatingActionButton(
      tooltip: 'Increment',
      onPressed: () {
        // We can then use the update method to changes the UI.
        store.update(refCounter, (x) => x + 1);
      },
      child: const Icon(Icons.add),
    );
  }
}

我们已经看到了使用 state_watcher 创建应用程序的最低要求,但如果我们想创建派生状态呢?
例如,假设我们想要另一个小部件来显示计数器是否可以被 3 整除。

这种状态由 Computed 声明。

final refDivisibleByThree = Computed((watch) {
  final counter = watch(refCounter);
  final divisibleByThree = (counter % 3) == 0;
  return divisibleByThree;
});

并且我们可以像 Provided 一样监视它。

class _DivisibleByThree extends WatcherStatelessWidget {
  const _DivisibleByThree();

  @override
  Widget build(BuildContext context, BuildStore store) {
    final divisibleByThree = store.watch(refDivisibleByThree);
    return Text('$divisibleByThree');
  }
}

默认情况下,_DivisibleByThree 小部件仅在新的计算值与先前的值不同时才会重新构建。因此,当计数器从 7 变为 8 时,_DivisibleByThree 小部件不会重新构建,因为这两个值都无法被 3 整除(divisibleByThree 都是 false)。

开发工具

state_watcher 具有一个 DevTools 扩展,可让您轻松调试应用程序中的状态更改,并查看哪个状态导致小部件重新构建。

devtools_extension