賞金將在 6 天后到期。此問題的答案有資格獲得 100聲望賞金。 Lars Flieger正在從有信譽的來源尋找答案。
我使用Overmind和離子反應:
表 1:
const { count } = useAppState()
const { increaseCount } = useActions()
return
<IonPage>
<IonContent>
<IonRouterLink routerLink='/tab1/page1'>1. Go to another page</IonRouterLink> // Go to page 1
<IonText><p>{count}</p></IonText>
<IonButton onClick={() => increaseCount()}>4. Increase again</IonButton>
</IonContent>
</IonPage>
第2頁:
const { count } = useAppState()
const { increaseCount } = useActions()
return
<IonPage>
<IonContent>
<IonBackButton defaultHref="/" /> // Go back to tab 1
<IonText><p>{count}</p></IonText>
<IonButton onClick={() => increaseCount()}>4. Increase again</IonButton>
</IonContent>
</IonPage>
當我這樣做時:
- 轉到另一個頁面
- 增加計數(修改狀態)
- 回傳主頁面
- 增加計數(修改狀態)==> 進入控制臺,出現錯誤
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
我創建了這個最小復制代碼:https ://github.com/dopeshot/ionic-overmind-cant-perform-state-update
我還制作了一個關于該問題的短視頻:https ://www.youtube.com/watch?v=5w6r1_lxoS8
我該如何解決這個問題?
uj5u.com熱心網友回復:
這個問題是 overmind-react 庫中的一個錯誤。如果您查看源代碼,您會看到當組件卸載時它們沒有將 設定mountedRef.current為 false,因此當狀態更改時,它會嘗試重新渲染卸載的組件。它應該在這里
https://github.com/cerebral/overmind/blob/cb095ffa0cd49504fed6bbc99054d89ba9b92ea3/packages/overmind-react/src/index.ts#L139
您可以克隆存盤庫,將以下更改添加到代碼中,并將依賴項指向您在 git 存盤庫中的版本(或發布您自己的包)
return () => {
mountedRef.current = false;
overmind.eventHub.emitAsync(EventType.COMPONENT_REMOVE, {
最好的辦法是打開一個 GitHub 問題,如果可能的話,用那個小改動打開 PR。但我不希望它很快得到解決,因為它似乎是一個只在開發中發生的問題。
uj5u.com熱心網友回復:
如果組件尚未安裝,則無需更新回呼中的狀態。
作為錯誤狀態:
錯誤警告:無法對未安裝的組件執行 React 狀態更新。
解決方案
宣告 let isMounted = trueinside useActions(或者useEffect,useAction不建議使用,并且不再真正支持,您可以閱讀redux 的創建者對此的評論),一旦組件被卸載,它將在清理回呼中更改。在狀態更新之前,您現在有條件地檢查此變數:
useEffect(() => {
let isMounted = true; // note mutable flag
someAsyncOperation().then(data => {
if (isMounted) setState(data); // add conditional check
})
return () => { isMounted = false }; // cleanup toggles value, if unmounted
}, []); // adjust dependencies to your needs
更徹底的解決方案:自定義useAsyncHook 我們可以將所有樣板封裝到自定義 Hook 中,如果組件卸載或依賴值之前發生更改,它會自動中止異步函式:
function useAsync(asyncFn, onSuccess) {
useEffect(() => {
let isActive = true;
asyncFn().then(data => {
if (isActive) onSuccess(data);
});
return () => { isActive = false };
}, [asyncFn, onSuccess]);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/417388.html
標籤:
