A widget that enables executing scoped reactive side-effects inline within the widget tree.
SignalEffect (and its direct type alias SignalListener) allows you to run side-effects
(such as showing snackbars, opening dialogs, navigating, or logging metrics) in response
to signal updates, without triggering rebuilds of the child widget tree.
The effect callback runs immediately on mount and dynamically tracks any signals accessed
within its scope. The underlying subscription is automatically disposed when this widget
is removed from the tree. You can optionally return a cleanup function (e.g. void Function())
to run before the next execution or when the widget is disposed.
Dialog and Snackbar Trigger Example#
final count = signal(0);
class SnackBarTrigger extends StatelessWidget {
const SnackBarTrigger({super.key});
@override
Widget build(BuildContext context) {
return SignalEffect(
effect: (context) {
// Triggers whenever 'count' updates:
if (count.value >= 10) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Limit reached: ${count.value}!')),
);
}
// Optional: return cleanup callback
return () => print('Cleaning up effect');
},
child: ElevatedButton(
onPressed: () => count.value++,
child: const Text('Increment and Watch'),
),
);
}
}
Important
Do not perform synchronous state changes or trigger widget rebuilds directly inside the effect callback to prevent infinite reactive loops.
Constructors#
View Constructors
SignalEffect({dynamic Function(BuildContext context)? effect, @Deprecated('Use effect instead') void Function(BuildContext context)? callback, required this.child, this.debugLabel, super.key})
Creates a SignalEffect widget.
The effect is executed inside a reactive effect. The child is rendered normally.
Properties#
View Properties
Widget child
The child widget to render.
String? debugLabel
Optional debug label for the effect.