mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
63 lines
2.4 KiB
Markdown
63 lines
2.4 KiB
Markdown
|
|
@name Disallowed function call inside reactive context
|
||
|
|
@category runtime
|
||
|
|
@shortDescription A disallowed function is called inside a reactive context
|
||
|
|
|
||
|
|
@description
|
||
|
|
A function that is not allowed to run inside a reactive context was called from within a reactive context.
|
||
|
|
|
||
|
|
For example, an `effect` cannot be scheduled from within a `computed` or an actively executing effect.
|
||
|
|
Avoid calling functions like `effect` as part of template expressions, as those execute in their own reactive context.
|
||
|
|
|
||
|
|
Computed expressions are expected to be pure.
|
||
|
|
Pure means that expression do not trigger any side effects.
|
||
|
|
Side effects are operations like scheduling `afterRender`, creating a new `effect`, or subscribing to observables.
|
||
|
|
|
||
|
|
Some operations are explicitly banned inside reactive contexts in order to avoid common pitfalls.
|
||
|
|
As an example, using `afterRender` inside a `computed` will schedule new render hooks every time the computed expression evaluates.
|
||
|
|
This is likely not intended and could degrade application performance.
|
||
|
|
|
||
|
|
### Fixing the error
|
||
|
|
|
||
|
|
This error guide is non-exhaustive.
|
||
|
|
It captures a few common scenarios and how to address the error.
|
||
|
|
|
||
|
|
#### `afterRender`
|
||
|
|
Move the call for `afterRender` outside of the reactive context.
|
||
|
|
|
||
|
|
A good place to schedule the after render hook is in the component's class constructor.
|
||
|
|
Alternatively, use `untracked` to leave the reactive context and explicitly opt-out of this error.
|
||
|
|
|
||
|
|
#### `effect`
|
||
|
|
Move the call for `effect` outside of the reactive context.
|
||
|
|
|
||
|
|
A good place to schedule an effect is in a `@Component`'s class constructor.
|
||
|
|
|
||
|
|
#### `toSignal`
|
||
|
|
Move the call for `toSignal` outside of the reactive context.
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
result = computed(() => {
|
||
|
|
const dataSignal = toSignal(dataObservable$);
|
||
|
|
return doSomething(dataSignal());
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
can be refactored into:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
dataSignal = toSignal(dataObservable$);
|
||
|
|
result = computed(() => doSomething(dataSignal()));
|
||
|
|
```
|
||
|
|
|
||
|
|
Alternatively, if this is not possible, consider manually subscribing to the observable.
|
||
|
|
|
||
|
|
As a last resort, use `untracked` to leave the reactive context.
|
||
|
|
Be careful as leaving the reactive context can result in signal reads to be ignored inside `untracked`.
|
||
|
|
|
||
|
|
@debugging
|
||
|
|
|
||
|
|
The error message mentions the function that was unexpectedly called.
|
||
|
|
Look for this function call in your application code.
|
||
|
|
|
||
|
|
Alternatively, the stack trace in your browser will show where the function was invoked and where it's located.
|