Flutter状态管理的终极利器-signals

2,685 阅读1分钟

signals状态管理

Signals是Flutter的状态管理工具,类似于Provider、BLoC和Riverpod。它采用观察者模式,设计轻量级,易于处理按钮按下和数据更新等事件。

signals简单使用

简单说明一下观察者设计模式: 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

增加软件包

flutter pub add signals

简单逻辑实现

  1. 初始化Signal。
  2. 监听观察Signal。
  3. 增加Signal的改变的逻辑。 代码如下所示:
import 'package:flutter/material.dart';
import 'package:signals/signals_flutter.dart';

void main() {
  runApp(const App());
}

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

  ThemeData createTheme(BuildContext context, Brightness brightness) {
    return ThemeData(
      colorScheme: ColorScheme.fromSeed(
        seedColor: Colors.blue,
        brightness: brightness,
      ),
      brightness: brightness,
      useMaterial3: true,
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: createTheme(context, Brightness.light),
      darkTheme: createTheme(context, Brightness.dark),
      themeMode: ThemeMode.system,
      home: const CounterExample(),
    );
  }
}

class CounterExample extends StatefulWidget {
  const CounterExample({super.key});

  @override
  State<CounterExample> createState() => _CounterExampleState();
}

class _CounterExampleState extends State<CounterExample> {
  late final Signal<int> counter = signal(0);

  void _incrementCounter() {
    counter.value++;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Counter'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Watch((context) => Text(
              '$counter',
              style: Theme.of(context).textTheme.headlineMedium,
            )),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Signal底层数据结构

使用Node类,Node底层的实现是双向链表,而替代原来的Set,主要是性能方面考虑,双向链表能够在O(1)时间复杂度找到他的前驱节点。

watch方法

还可以使用Signal.watch(context)扩展方法,可用于在信号改变时重建Widget。示例代码如下所示:

Text(
              '${counter.watch(context)}',
              style: Theme.of(context).textTheme.headlineMedium,
            )

总结

signals是一种反应原语——一种存储状态的方式,当值发生变化时自动通知监听器,而不需要setState、Provider或其他重量级解决方案。

参考资料

pub.dev/packages/si…

dartsignals.dev/

preactjs.com/blog/signal…