Effect 与批处理
基础 Effect
dart
final count = signal(context, 0);
final stop = effect(context, () {
debugPrint('count = ${count()}');
});
// 手动停止
stop();清理回调
onEffectCleanup 用于重新执行前清理,onEffectDispose 用于最终清理。
dart
effect(context, () {
onEffectCleanup(() => debugPrint('cleanup before re-run'));
onEffectDispose(() => debugPrint('dispose'));
});EffectScope
dart
final scope = effectScope(context, () {
effect(context, () => debugPrint('A'));
effect(context, () => debugPrint('B'));
});
scope(); // 释放范围内所有 effect批处理更新
dart
batch(() {
a.set(a() + 1);
b.set(b() + 1);
});Flutter 示例(来自 example 应用)
dart
class EffectBatchSection extends StatelessWidget {
const EffectBatchSection({super.key});
@override
Widget build(BuildContext context) {
final a = signal<int>(context, 1);
final b = signal<int>(context, 2);
final sum = computed<int>(context, (_) => a() + b());
final effectRuns = signal<int>(context, 0);
effect(context, () {
sum();
final current = untrack(() => effectRuns());
effectRuns.set(current + 1);
});
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('a: ${a()} b: ${b()} sum (computed): ${sum()}'),
Text('effect runs: ${effectRuns()}'),
const SizedBox(height: 8),
Wrap(
spacing: 8,
children: [
ElevatedButton(
onPressed: () => a.set(a() + 1),
child: const Text('Increment A'),
),
ElevatedButton(
onPressed: () => b.set(b() + 1),
child: const Text('Increment B'),
),
OutlinedButton(
onPressed: () {
batch(() {
a.set(a() + 1);
b.set(b() + 1);
});
},
child: const Text('Batch +1 both'),
),
],
),
],
);
}
}