ANGULAR SIGNALS
Angular has recently embraced signals into its core and it's for very good reasons.
In this article, I'll talk about the said reasons as well as what signals are.
Table of contents:
1. What are signals?
2. How Signals Work?
3. Why Signals?
4. Signals VS Behavior Subject
5. Reactivity and Change Detection
1. WHAT ARE SIGNALS?
A Signal is a wrapper around a value that exposes ways to react to whenever the said value changes. It works in a very similar way that Observables do, since a form of subscription is necessary to be able to listen and react to changes.
However, you don't have to manually manage subscriptions like you do when working with Observables due to the fact that they're managed behind the scenes for you.
Signals can hold any type of value, from primitives to complex data structures.
Also, it's important to notice that Signals can be either writable or read-only.
2. HOW DO SIGNALS WORK?
Like we have seen before, a Signal holds a value, any kind of value for that matter.
Because it's a wrapper around a value, it exposes interesting ways to interact with the value it holds, and it does that through special methods.
Let's talk about these methods:
2.1 - The Signal Call
In order to create a signal, you need to call it and pass a value to it, like this:
const counter = signal(0);
This call creates a signal that holds the value 0.
2.2 - Signal Setters
A Signal provides setters to update, mutate and set a new value. Let's check out every single one of them:
2.2.1 - Set
The set function allows you to completely replace the current value of a Signal with a new one.
The following is its signature:
set(value: T): void
It takes a generic value that replaces whatever the current value is.
Example:
const count = signal(0)
counter.set(1)
Now the current value of the counter signal is 1.
2.2.2 - Mutate
The mutate method allows you to, as the name suggests, mutate the current value of a signal, which means you do it without losing its original reference in memory.
The following is its signature:
mutate(mutatorFn: (value: T) => void): void;
It takes a callback that takes a generic value that will become the signal's current value.
Example:
领英推荐
const bands = signal<Band[]>([])
bands.push({ name: 'Led Zeppelin', genre: 'rock' })
As you can see, we're changing the contents of the bands array without changing its reference.
2.2.3 - Update
The update method allows you to use immutability to change the current value of a Signal, which means you will change the reference in memory for the signal whenever the update method is called.
The following is its signature:
update(updateFn: (value: T) => T): void
It takes a callback that takes a generic value that will be merged with whatever the current value of the signal happens to be.
Example:
const counter = signal(0)
counter.update(value => value + 1);
2.2 - The computed function
The computed function returns a memoized value, which means it caches the values it returns so, whenever the computed function is called using the same arguments, the cached values will be returned instead of processing its operations unnecessarily, which is great in terms of performance.
Example:
const counter = signal(0);
const isEqual = computed(() => counter() === 5);
As you can see, the computed function depends on counter, so whenever counter is updated, the computed function reacts to that change so, everything that reads from isEqual gets notified about its updates.
2.3 - Signal Effects
Signal Effects are tree-shakable functions that are called whenever the value of a Signal is changed.
This function allows us to perform special actions in response to Signal changes.
Example:
const age = signal(10);
effect(() => {
console.log('Age is:', this.age());
});
age.set(20);
age.set(30);
Output:
// Age is: 10
// Age is: 20
// Age is: 30
Signal Effects are pretty much listeners. They listen to signal changes and are called in response to the said changes.
Now that we've wrapped our heads around how Signals work, let's talk about why Angular has embraced them.
3. WHY SIGNALS?
Because Signals are primitives that allow us to work with reactivity, the Angular Team has realized that they can improve the performance of Angular applications drastically. And the reason why that is, it's because they pretty much discard the necessity for Zone.js and its expensive impact on change detection.
4. SIGNALS VS BEHAVIOR SUBJECT
You may have noticed how similar Signals and Behavior Subject are. They both take an initial value and they both notify their subscriptions about changes, whenever they occur.
However, when it comes to Behavior Subject, you have to manually manage the subscriptions, meaning, you have to make sure you're not forgetting to unsubscribe from Behavior Subject Streams when you don't need them active, so you can avoid memory leaks.
Doing that manually can easily lead to problems that are hard to keep track of, and that's another thing that Signals do really well because you don't need to manually managed subscriptions, they're taken care of behind the scenes for you.
5. REACTIVITY AND CHANGE DETECTION
Angular has been using the Zone.js library to keep track of dynamic changes for quite a long time.
As you may know, the zone created ( ngZone ) reacts to changes by checking the whole tree of components from top to bottom, which is the default change detection strategy used by Angular.
However, if you really understand change detection well enough, you can rely on the OnPush strategy to tell Angular to only trigger change detection for components that have updated their @Inputs, or the async pipe they use have gotten a new emitted value from the streams they're subscribed to.
Even though there are ways to reduce the impact this change detection system has on the performance of Angular applications, it doesn't change the fact that they're quite complicated to understand, let alone apply them effectively.
That's another aspect that makes Signals the perfect alternative, because we can pretty much let the framework keep track of Signal changes as opposed to rely on Zone.js and the expensive change detection system to know when components need to be updated.
CONCLUSION
Angular Signals will change the way Angular applications are built, and it's definitely for the better.
I have been quite excited to see where they'll lead us, and I hope you feel the same about it.
Thank you so much for your time, I really appreciate it.