Can't?perform?a?React?state?update?on?an?unmounted?component報(bào)錯(cuò)解決
總覽
為了解決"Warning: Can't perform a React state update on an unmounted component" ,可以在你的useEffect鉤子中聲明一個(gè)isMounted布爾值,用來(lái)跟蹤組件是否被安裝。一個(gè)組件的狀態(tài)只有在該組件被掛載時(shí)才會(huì)被更新。
import {useState, useEffect} from 'react';
const App = () => {
const [state, setState] = useState('');
useEffect(() => {
// ??? set isMounted to true
let isMounted = true;
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ??? only update state if component is mounted
if (isMounted) {
setState(result);
}
}
fetchData();
return () => {
// ??? when component unmounts, set isMounted to false
isMounted = false;
};
}, []);
return (
<div>
<h2>State: {JSON.stringify(state)}</h2>
</div>
);
};
export default App;
當(dāng)我們?cè)噲D更新一個(gè)未掛載的組件的狀態(tài)時(shí),會(huì)出現(xiàn)"無(wú)法在未掛載的組件上執(zhí)行React狀態(tài)更新"的警告。
isMounted
擺脫該警告的直截了當(dāng)?shù)姆绞绞?,?code>useEffect鉤子中使用isMounted布爾值來(lái)跟蹤組件是否被掛載。
在useEffect中,我們初始化isMounted布爾值為true。
我們的fetchData 函數(shù)執(zhí)行一些異步的任務(wù),最常見(jiàn)的是一個(gè)API請(qǐng)求,并根據(jù)響應(yīng)來(lái)更新?tīng)顟B(tài)。
然而,需要注意的是,我們只有當(dāng)isMounted變量被設(shè)置為true時(shí),才會(huì)更新?tīng)顟B(tài)。
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ??? only update state if component is mounted
if (isMounted) {
setState(result);
}
}
這可以幫助我們避免警告,因?yàn)槿绻M件沒(méi)有掛載,我們就不會(huì)更新?tīng)顟B(tài)。
當(dāng)組件卸載時(shí),從useEffect鉤子返回的函數(shù)會(huì)被調(diào)用。
return () => {
// ??? when component unmounts, set isMounted to false
isMounted = false;
};
我們?cè)O(shè)置isMounted變量為false,表示該組件不再掛載。如果fetchData函數(shù)在組件卸載時(shí)被調(diào)用,if代碼塊不會(huì)執(zhí)行是因?yàn)?code>isMounted設(shè)置為false。
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ??? only update state if component is mounted
if (isMounted) {
setState(result);
}
}
提取
如果經(jīng)常這樣做,可以將邏輯提取到可重用的鉤子中。
import {useState, useEffect, useRef} from 'react';
// ??? extract logic into reusable hook
function useIsMounted() {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
});
return isMounted;
}
const App = () => {
const [state, setState] = useState('');
// ??? use hook
const isMountedRef = useIsMounted();
useEffect(() => {
async function fetchData() {
const result = await Promise.resolve(['hello', 'world']);
// ??? only update state if component is mounted
if (isMountedRef.current) {
setState(result);
}
}
fetchData();
}, [isMountedRef]);
return (
<div>
<h2>State: {JSON.stringify(state)}</h2>
</div>
);
};
export default App;
useRef()鉤子可以傳遞一個(gè)初始值作為參數(shù)。該鉤子返回一個(gè)可變的ref對(duì)象,其.current屬性被初始化為傳遞的參數(shù)。
我們?cè)?code>useIsMounted鉤子中跟蹤組件是否被掛載,就像我們直接在組件的useEffect鉤子中做的那樣。
需要注意的是,在fetchData函數(shù)中,我們必須檢查isMountedRef.current 的值,因?yàn)?code>ref上的current屬性是ref的實(shí)際值。
翻譯原文鏈接:bobbyhadz.com/blog/react-…
以上就是Can't perform a React state update on an unmounted component報(bào)錯(cuò)解決的詳細(xì)內(nèi)容,更多關(guān)于React state update報(bào)錯(cuò)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- React報(bào)錯(cuò)Type '() => JSX.Element[]' is not assignable to type FunctionComponent
- React報(bào)錯(cuò)Element type is invalid解決案例
- React報(bào)錯(cuò)Function?components?cannot?have?string?refs
- React報(bào)錯(cuò)Too many re-renders解決
- 解決React報(bào)錯(cuò)Property 'X' does not exist on type 'HTMLElement'
- Objects are not valid as a React child報(bào)錯(cuò)解決
- 解決React報(bào)錯(cuò)No duplicate props allowed
- 解決React報(bào)錯(cuò)React.Children.only expected to receive single React element child
相關(guān)文章
react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist
這篇文章主要為大家詳細(xì)介紹了react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
react實(shí)現(xiàn)一個(gè)優(yōu)雅的圖片占位模塊組件詳解
這篇文章主要給大家介紹了關(guān)于react如何實(shí)現(xiàn)一個(gè)還算優(yōu)雅的占位模塊圖片組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
React Native中WebView與html雙向通信遇到的坑
這篇文章主要介紹了React Native中WebView與html雙向通信的一些問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解
這篇文章主要為大家介紹了ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
react創(chuàng)建項(xiàng)目啟動(dòng)報(bào)錯(cuò)的完美解決方法
這篇文章主要介紹了react創(chuàng)建項(xiàng)目啟動(dòng)報(bào)錯(cuò)的完美解決方法,全稱(chēng)為Node Package Manager,是隨同NodeJS一起安裝的包管理工具,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
react性能優(yōu)化useMemo與useCallback使用對(duì)比詳解
這篇文章主要為大家介紹了react性能優(yōu)化useMemo與useCallback使用對(duì)比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

