錯誤百科

在反應式情境中呼叫不允許的函式

不允許在反應式情境中執行的函式,從反應式情境內部被呼叫了。

例如,effect 不能從 computed 或正在執行中的 effect 內部排程。 避免把 effect 這類函式作為範本表達式的一部分呼叫,因為它們在自己的反應式情境中執行。

計算表達式預期是純粹的。 純粹表示表達式不會觸發任何副作用。 副作用是像排程 afterNextRender/afterEveryRender、建立新的 effect,或訂閱 observable 這類操作。

有些操作在反應式情境中被明確禁止,以避免常見的陷阱。 例如,在 computed 內使用 afterNextRender/afterEveryRender,會在每次計算表達式求值時排程新的渲染勾點。 這很可能不是預期行為,並可能降低應用程式效能。

修正方式

本錯誤指南並未涵蓋所有情況。 它列出幾個常見情境以及如何處理此錯誤。

afterNextRender/afterEveryRender

把 afterNextRender/afterEveryRender 的呼叫移到反應式情境之外。

排程渲染後勾點的好位置是元件的類別建構函式。 或者,使用 untracked 離開反應式情境,明確退出此錯誤的檢查。

effect

把 effect 的呼叫移到反應式情境之外。

排程 effect 的好位置是 @Component 的類別建構函式。

toSignal

把 toSignal 的呼叫移到反應式情境之外。

result = computed(() => {
  const dataSignal = toSignal(dataObservable$);
  return doSomething(dataSignal());
});

可以重構為:

dataSignal = toSignal(dataObservable$);
result = computed(() => doSomething(dataSignal()));

或者,如果無法這麼做,請考慮手動訂閱 observable。

作為最後手段,使用 untracked 離開反應式情境。 請小心,因為離開反應式情境可能導致 untracked 內的訊號讀取被忽略。

除錯方式

錯誤訊息會提到被非預期呼叫的函式。 在你的應用程式程式碼中找出該函式呼叫。

或者,瀏覽器中的堆疊追蹤會顯示該函式被呼叫的位置以及它所在的位置。