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ù),最常見的是一個(gè)API請(qǐng)求,并根據(jù)響應(yīng)來(lái)更新狀態(tài)。
然而,需要注意的是,我們只有當(dāng)isMounted
變量被設(shè)置為true
時(shí),才會(huì)更新狀態(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à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報(bào)錯(cuò)之Parameter event implicitly has a
這篇文章主要為大家介紹了React報(bào)錯(cuò)之Parameter event implicitly has an any type,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08React錯(cuò)誤邊界Error Boundaries
錯(cuò)誤邊界是一種React組件,這種組件可以捕獲發(fā)生在其子組件樹任何位置的JavaScript錯(cuò)誤,并打印這些錯(cuò)誤,同時(shí)展示降級(jí)UI,而并不會(huì)渲染那些發(fā)生崩潰的子組件樹2023-01-01React如何解決fetch跨域請(qǐng)求時(shí)session失效問(wèn)題
這篇文章主要給大家介紹了關(guān)于React如何解決fetch跨域請(qǐng)求時(shí)session失效問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11關(guān)于React狀態(tài)管理的三個(gè)規(guī)則總結(jié)
隨著 JavaScript 單頁(yè)應(yīng)用開發(fā)日趨復(fù)雜,JavaScript 需要管理比任何時(shí)候都要多的 state (狀態(tài)),這篇文章主要給大家介紹了關(guān)于React狀態(tài)管理的三個(gè)規(guī)則,需要的朋友可以參考下2021-07-07前端 react 實(shí)現(xiàn)圖片上傳前壓縮(縮率圖)
這篇文章主要介紹了前端 react 實(shí)現(xiàn)圖片上傳前壓縮(縮率圖),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08react中ref獲取dom或者組件的實(shí)現(xiàn)方法
這篇文章主要介紹了react中ref獲取dom或者組件的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05react18?hooks自定義移動(dòng)端Popup彈窗組件RcPop
這篇文章主要介紹了react18?hooks自定義移動(dòng)端Popup彈窗組件RcPop,react-popup?基于react18+hook自定義多功能彈框組件,整合了msg/alert/dialog/toast及android/ios彈窗效果,需要的朋友可以參考下2023-08-08