Signals
Last updated
Last updated
A signal is a wrapper around a value that notifies interested consumers when that value changes. (Values may be primitive or complex data structures)
Signals gives Angular a new way of handling data changes and updating the UI, instead of just Change Detection
.
You read a signal's value by calling its getter function, which allows Angular to track where the signal is used.
Avoid using effect()
for propagation of state changes.
This might lead to infinite circular updates, or unnecessary change detection cycles.
Angular will forbid you from change signal states inside effect()
.
Don't mutate signal values when updating them, always give them new values.
signal()
Can be created with signal(value)
.
You may update their values with:
set(newValue)
to just set a new value.
update((oldValue) => newValue)
, to access the old value.
computed()
Are readonly signals that derive their value from other signals.
Created with computed(() => this.otherSignal() + 1)
.
Computed signals depend on other signals, so computed signals are only updated when their dependee signals update.
Computed signals are both lazily evaluated and memoized.
lazily evaluated
means that they do not run to calculate its value until the first time you read their value.
memoized
means that its value is cached, so they wont be recalculated all the time. (Only when their dependee signal value changes)
As a result of this, you can safely perform computationally expensive derivations in them, like filtering arrays.
Computed signals dependencies are dynamic.
Only signals that were actually read during the derivation are tracked. (And they can change on runtime)
In this example:
When showCount
is false
, updating count
will not trigger a recomputation of the computed signal.
So only showCount
change will trigger.
But when showCount
is true
, count
signal can be read, and now the computed signal will recalculate itself on both showCount
and count
updates.
Just remeber that the computed signal won't recalculate immediatly after the dependee signals update, but only when conditionalCount
is read again.
effect()
Effects are operations that runs whenever on or more signal values change.
They also have dependee signals, which are the signals used inside them.
When these dependee signals values change, the effect re-runs.
Create them with effect(() => {})
.
Effect always run at least once.
Effects also keep track of their dependencies dynamically.
So they will only track signals that were read during the last execution.
Effects always execute asynchronously
, during the change detection process.
By default Angular prevents updates
to signals inside effects.
Effects are good for:
Logging data.
Keeping data in sync with window.localStorage
.
Performing custom rendering to a <canvas>
, charting library, or other third party UI library.
Don't use Signals for propagation of state changes, potentially resulting in infinite circular updates, or unnecessary change detection cycles.
Effects are destroyed automatically when their Components, Directives, Services, etc are destroyed.
You can create effect
outside of a constructor
or assign specific names to it by:
To avoid re-run of effects when signal values are updated, wrap the signals with untracked()
.
untracked
is also useful when an effect needs to invoke some external code which shouldn't be treated as a dependency.
Effect might start long-running operations, which you should cancel if the effect is destroyed or runs again before the first operation finished.
When creating effects, you can optionally pass an onCleanup
function as its first parameter. And this onCleanup
accepts a callback function that is invoked before the next run of the effect begins, or when the effect is destroyed.
By deafult, you can only create effect()
within an .