In the Angular Signal system, a Reactive Context is a special environment where Angular’s "dependency tracking engine" is turned on. It is the invisible bubble that allows Signals to know who is watching them.
If you read a Signal inside a reactive context, you are automatically "subscribed" to it. If you read a Signal outside of one, it’s just a normal function call with no future updates.
What creates a Reactive Context?
Only a few specific places in Angular create this special environment:
-
template: When you call
mySignal()in your HTML, the template creates a reactive context. -
computed(): The function inside a computed signal is a reactive context. -
effect(): The function body of an effect is a reactive context.
Things to remember when working in reactive context
- Its Ok to use signals inside effect
constructor() {
effect(() => {
const x = mySignal() // ✅ this is fine
});
}
Don't do this
- ❌ Causing side effects.
- ❌ Creating or updating signals inside reactive context
readonly x = signal(0);
readonly y = signal(0);
readonly c = computed(() => {
const total = this.x() + this.y();
return {sum : signal(total)}; // ❌ BAD practice
});
readonly x = signal(0);
readonly c = computed(() => {
this.x.update(v => v + 1); // ❌ BAD practice
});
- ❌ Calling API which could update signals
- ❌ Changing DOM directly
- Avoid conditional effects like:
- ❌ Creating effect inside effect. It’s technically possible but creates a nightmare for memory management and logic flow.
- ❌ Creating signal inside effect
effect(()=> {
if (this.x() > 10) {
effect(() => console.log(this.x())); // ❌ BAD practice
}
});
- Effects are meant to trigger changes but not to other signals
Signal change batching in Angular
It refers to the process where angular groups multiple signal changes together and process them at once rather than individually. This helps to improve performance by reducing unnecessary re-execution of effects and re-computations. And because of batching, you should not change signals in side effects.
Angular lets you run your code synchronously. It tracks all the signals that you modify and then when the task is completed, it schedules a code that checks for changes and then decides which effects to run.
If inside one of the effects you modify a signal, you can think about it as doing it too late. This can cause cyclic dependencies or infinite loops.
So effects should only focus on things like logging, rendering things that do not affect changes in signals.
It is a good practice not to run, not to trigger business logic inside effects, because you can never know which services or APIs in your business logic may cause signals to change.
So you might ask yourself, what should I do with effects?
Effects should mostly be used for things like logging, rendering, updating local storage. And in fact, when you think about rendering, this is exactly what angular does. Every one of your templates is run like an effect. So when you change signals, the template is re-evaluated pretty much like any other code running inside an effect.
So this is how the mechanism of change detection without zone works.
Thanks for reading. Happy coding!!!
References:
Top comments (0)