Watch<T extends Widget> class
Watch
To watch a signal for changes in Flutter, use the Watch
widget. This will only rebuild this widget method and not the entire widget tree.
final signal = signal(10);
...
@override
Widget build(BuildContext context) {
return Watch((context) => Text('$signal'));
}
This will also automatically unsubscribe when the widget is disposed.
Any inherited widgets referenced to inside the Watch scope will be subscribed to for updates (MediaQuery, Theme, etc.) and retrigger the builder method.
There is also a drop in replacement for builder:
final signal = signal(10);
...
@override
Widget build(BuildContext context) {
- return Builder(
+ return Watch.builder(
builder: (context) => Text('$signal'),
);
}
.watch(context)
If you need to map to a widget property use the watch
extension method. This will infer the type and subscribe to the signal.
final fontSize = signal(10);
...
@override
Widget build(BuildContext context) {
return Text('Hello World',
style: TextStyle(fontSize:fontSize.watch(context)),
);
}
It is recommended to use Watch
instead of .watch(context)
as it will automatically unsubscribe when the widget is disposed instead of waiting on the garbage collector via WeakReferences.
.listen(context, cb)
Alternatively if need to listen for changes to a signal but not rebuild the widget you can use the listen extension.
final counter = signal(0);
...
@override
Widget build(BuildContext context) {
counter.listen(context, () {
if (counter.value == 10) {
final messenger = ScaffoldMessenger.of(context);
messenger.hideCurrentSnackBar();
messenger.showSnackBar(
const SnackBar(content: Text('You hit 10 clicks!')),
);
}
});
...
}
This can be used in the build method and will call the callback method in the same way it would rebuild the widget (only when mounted).
Rebuilds
To protect against unnecessary rebuilds, the watch
extension will only subscribe once to the nearest element and mark the widget as dirty.
This means that if you have multiple widgets that are watching the same signal, only the first one will be subscribed to the signal and multiple updates will be batched together.
It is also possible to isolate the rebuilds with the Builder
widget, however it is recommended to use Watch
or SignalWidget
instead.
final signal = signal(10);
...
@override
Widget build(BuildContext context) {
// Called once
return Column(
children: [
Builder(
builder: (context) {
// Called every time the signal changes
final count = signal.watch(context);
return Text('$count');
},
),
Text('Not rebuilt'),
],
);
}
Selectors
With signals instead of using select
you instead create a new computed
signal that is derived from the original signal.
final signal = signal((a: 1, b: 2));
final computed = computed(() => signal.value.a);
...
@override
Widget build(BuildContext context) {
return Watch((_) => Text('$computed'));
}
It is also possible to select from the signal directly:
final signal = signal((a: 1, b: 2));
final computed = signal.select((s) => s.value.a);
...
@override
Widget build(BuildContext context) {
return Watch((_) => Text('$computed'));
}
- Inheritance
Constructors
-
Watch(T builder(BuildContext context), {Key? key, String? debugLabel, List<
ReadonlySignal> dependencies = const []}) -
Minimal builder for signal changes that rerender a widget tree.
const
-
Watch.builder({Key? key, required T builder(BuildContext context), String? debugLabel, List<
ReadonlySignal> dependencies = const []}) -
Drop in replacement for the Flutter builder widget.
const
Properties
- builder → T Function(BuildContext context)
-
The widget to rebuild when any signals change
final
- debugLabel → String?
-
Optional debug label to use for devtools
final
-
dependencies
→ List<
ReadonlySignal> -
List of optional dependencies to watch
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< Watch< T> > -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited