Computed
A computed signal is a signal that depends on other signals.
To create a computed signal, you have to use the Computed
class.
A Computed
automatically subscribes to any signal provided and reruns when any of them change.
final name = Signal('John');
final lastName = Signal('Doe');
final fullName = Computed(() => '${name.value} ${lastName.value}');
print(fullName()); // prints "John Doe"
// Update the name
name.set('Jane');
print(fullName()); // prints "Jane Doe"
You may want to subscribe only to a sub-field of a Signal
value.
// sample User class
class User {
const User({
required this.name,
required this.age,
});
final String name;
final int age;
User copyWith({
String? name,
int? age,
}) {
return User(
name: name ?? this.name,
age: age ?? this.age,
);
}
}
// create a user signal
final user = Signal(const User(name: "name", age: 20));
// create a derived signal just for the age
final age = Computed(() => user().age);
// adding an effect to print the age
Effect(() {
print('age changed from ${age.previousValue} into ${age.value}');
});
// just update the name, the effect above doesn't run because the age has not changed
user.updateValue((value) => value.copyWith(name: 'new-name'));
// just update the age, the effect above prints
user.updateValue((value) => value.copyWith(age: 21));
A derived signal is not of type Signal
but is a ReadSignal
.
The difference with a normal Signal
is that a ReadSignal
doesn't have a value setter, in other words it's a read-only signal.
You can also use derived signals in other ways, like here:
final counter = Signal(0);
final doubleCounter = Computed(() => counter() * 2);
Every time the counter
signal changes, the doubleCounter updates with the new doubled counter
value.
You can also transform the value type into a bool
:
final counter = Signal(0); // type: int
final isGreaterThan5 = Computed(() => counter() > 5); // type: bool
isGreaterThan5
will update only when the counter
value becomes lower/greater than 5
.
- If the
counter
value is0
,isGreaterThan5
is equal tofalse
. - If you update the value to
1
,isGreaterThan5
doesn't emit a new value, but still containsfalse
. - If you update the value to
6
,isGreaterThan5
emits a newtrue
value.