关于 signals-hooks
这份指南介绍如何在基于 flutter_hooks 的 Flutter 应用中使用 signals_hooks 管理响应式状态。内容包括信号、派生状态、异步任务、集合及通知器桥接,并说明组件生命周期清理。
主要功能
- 01创建和管理响应式信号
- 02派生计算状态与异步状态
- 03将副作用绑定到组件生命周期
- 04将 Flutter 通知器桥接为信号
- 05跟踪响应式集合与历史状态
适用场景
- 01在 HookWidget 中管理信号状态
- 02订阅外部信号
- 03将 ValueNotifier 接入 signals
- 04使用 HookBuilder 测试 hooks
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ rodydavis/ signals.dart --skill signals_hooks安装后在 Claude Code 中输入/signals_hooks确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CONTEXT.mdhooks/CONTEXT.mduse-async-computed.mduse-async-signal.mduse-change-stack-signal.mduse-computed.mduse-existing-signal.mduse-future-signal.mduse-iterable-signal.mduse-lazy-signal.mduse-linked-signal.mduse-list-signal.mduse-map-signal.mduse-queue-signal.mduse-set-signal.mduse-signal-effect.mduse-signal-value.mduse-signal.mduse-stream-signal.mduse-tracked-signal.mduse-value-listenable-to-signal.mduse-value-notifier-to-signal.mduseAsyncComputed.mduseAsyncSignal.mduseChangeStackSignal.mduseComputed.mduseConnect.mduseExistingSignal.mduseFutureSignal.mduseIterableSignal.md详细介绍
响应式状态 Hook(signals_hooks)
本技能介绍如何在使用 signals_hooks 包的 flutter_hooks 代码库中编排响应式状态信号。
🚀 快速入门
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:signals_hooks/signals_hooks.dart';
class ExampleWidget extends HookWidget {
const ExampleWidget({super.key});
@override
Widget build(BuildContext context) {
// 1. Create a reactive signal managed by the widget's hook lifecycle
final count = useSignal(0);
// 2. Derive a lazy, memoized computed value
final doubleCount = useComputed(() => count.value * 2);
// 3. Register reactive side effects automatically bound to layout phases
useSignalEffect(() {
debugPrint('count changed: $count, double: $doubleCount');
});
return Scaffold(
body: Center(
child: Text('Count: $count (Double: $doubleCount)'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => count.value++,
child: const Icon(Icons.add),
),
);
}
}
提示
使用
use...方法在标准HookWidget元素中创建的所有信号、派生计算状态和副作用,都会在组件卸载时自动清理和释放。这彻底消除了内存泄漏或手动释放资源的问题。
📊 Hook 完整参考目录
下表汇总了 signals_hooks 包中所有可用的响应式 Hook。点击任意 Hook 的名称,即可查看其详细文档、签名、最佳实践和代码示例。
| Hook | 返回类型 | 描述 | 生命周期 / 清理行为 |
|---|---|---|---|
| useSignal | Signal<T> | 创建由 Hook 生命周期管理的可变响应式信号。 | 组件卸载时释放信号。 |
| useComputed | Computed<T> | 创建派生的、带缓存的只读计算信号。 | 组件卸载时释放计算信号。 |
| useSignalEffect | void | 注册与组件挂载生命周期绑定的响应式副作用。 | 组件卸载时取消副作用订阅。 |
| useExistingSignal | Signal<T> | 绑定外部信号,在其发生变化时触发重建。 | 卸载时解除订阅(不会释放信号)。 |
| useSignalValue | T | 直接读取并订阅外部信号的值。 | 卸载时解除订阅(不会释放信号)。 |
| useLazySignal | Signal<T> | 创建一个延迟初始化的新 Signal,由 Hook 状态管理。 | 组件卸载时释放延迟信号。 |
| useLinkedSignal | LinkedSignal<T> | 创建一个新的 LinkedSignal,其源发生变化时会重置自身的值。 | 组件卸载时释放关联信号。 |
| useFutureSignal | FutureSignal<T> | 创建具有自动释放和竞态保护功能的响应式 Future 信号。 | 组件卸载时释放 Future 信号。 |
| useStreamSignal | StreamSignal<T> | 创建基于键重新订阅的响应式流信号。 | 卸载时取消流订阅并释放信号。 |
| useAsyncSignal | AsyncSignal<T> | 将异步任务状态封装在可管理的 AsyncSignal 中。 | 组件卸载时释放异步信号。 |
| useAsyncComputed | AsyncSignal<T> | 创建在依赖项发生变化时重新求值的异步计算信号。 | 组件卸载时释放异步信号。 |
| useValueNotifierToSignal | Signal<T> | 将标准 Flutter ValueNotifier 桥接到可变响应式 Signal。 | 卸载时解除订阅(不会释放信号)。 |
| useValueListenableToSignal | ReadonlySignal<T> | 将标准 Flutter ValueListenable 桥接到只读 Signal。 | 卸载时解除订阅(不会释放信号)。 |
| useListSignal | ListSignal<T> | 创建可深度追踪元素级变更的响应式列表。 | 组件卸载时释放列表信号。 |
| useSetSignal | SetSignal<T> | 创建可深度追踪元素级变更的响应式集合。 | 组件卸载时释放集合信号。 |
| useMapSignal | MapSignal<K, V> | 创建可深度追踪键值变更的响应式映射。 | 组件卸载时释放映射信号。 |
| useIterableSignal | IterableSignal<T> | 创建可追踪元素级变更的响应式可迭代对象。 | 组件卸载时释放可迭代信号。 |
| useTrackedSignal | TrackedSignal<T> | 创建会记住历史值状态的追踪信号。 | 组件卸载时释放追踪信号。 |
| useQueueSignal | QueueSignal<T> | 创建用于 FIFO 集合管理的响应式队列。 | 组件卸载时释放队列信号。 |
| useChangeStackSignal | ChangeStackSignal<T> | 创建变更堆栈信号,以可靠地追踪撤销 / 重做历史记录。 | 组件卸载时释放变更堆栈信号。 |
🧪 测试状态 Hook
要验证 Hook 状态组件,请将 flutter_test 与 HookBuilder 搭配使用,以便在测试框架中安全地执行这些 Hook:
testWidgets('useSignal test', (tester) async {
late Signal<int> state;
await tester.pumpWidget(
HookBuilder(builder: (context) {
state = useSignal(42);
return Text('$state', textDirection: TextDirection.ltr);
}),
);
expect(state.value, 42);
expect(find.text('42'), findsOneWidget);
state.value = 43;
await tester.pumpAndSettle();
expect(find.text('43'), findsOneWidget);
});
评论
支持 Markdown