詳解React組件卸載怎么中止遞歸方法
問題的出現(xiàn)——組件卸載怎么中止遞歸方法
朋友在處理彈幕相關業(yè)務的時候,出現(xiàn)了一個bug:組件中的方法在組件卸載后仍然在執(zhí)行。代碼片段發(fā)給我看,但是變量的用意我也不懂,只看到有方法調用自身方法,這不就是遞歸嘛(最后發(fā)現(xiàn)是定時器沒有清除的問題)??。
遞歸的中止這還不簡單,在方法中添加一個中止條件不就好了。
const Children = () => {
const [isStop, setStop] = useState(false)
// 遞歸
const recursion = async (num: number) => {
if (isStop) return
console.log(num)
await sleep(1000)
recursion(num + 1)
}
useEffect(() => {
recursion(1)
return () => {
setStop(() => true)
}
}, [])
return (
<div>Children</div>
)
}
const HomePage: React.FC = () => {
const [flag, setFlag] = useState(false)
return (
<div>
<Button onClick={() => setFlag(!flag)}>點擊</Button>
{
flag && <Children></Children>
}
</div>
);
};

結果與預期好像不太一樣,突然仔細想一下,當組件卸載時,所有與該組件相關的狀態(tài)(通過useState定義的狀態(tài))都會被清除,這怎么可能會有效呢!
簡單閉包處理
既然狀態(tài)在組件卸載的時候被清理了,那么在遞歸內部增加狀態(tài)來控制遞歸不就行了。閉包就很適合現(xiàn)在的場景。
const controller = () => {
// 遞歸的狀態(tài)(開始/結束)
let state = false
// 遞歸方法
const recursion = async (num: number) => {
// 結束條件
if (state === false) return
console.log(num)
await sleep(1000)
recursion(num + 1)
}
return {
// 開啟遞歸
start: (num: number) => {
state = true
recursion(num)
},
// 結束遞歸
close: () => state = false
}
}
我們在掛載結束后創(chuàng)建一個單一實例用來控制遞歸方法,并在卸載的時候將遞歸的狀態(tài)改為false即可。如果需要在組件的其他位置使用,還是使用useRef對實例進行包裹比較好。
useEffect(() => {
let c = controller()
c.start(1)
return () => {
c.close()
}
}, [])

Hook useRef處理
const Children = () => {
const isUnmounted = useRef(false);
// 遞歸
const recursion = async (num: number) => {
if (isUnmounted.current) return
console.log(num)
await sleep(1000)
recursion(num + 1)
}
useEffect(() => {
recursion(1)
return () => {
isUnmounted.current = true
}
}, [])
return (
<div>Children</div>
)
}
const HomePage: React.FC = () => {
const [flag, setFlag] = useState(false)
return (
<div>
<Button onClick={() => setFlag(!flag)}>點擊</Button>
{
flag && <Children></Children>
}
</div>
);
};
來自CHAT-GPT
這是因為
useRef創(chuàng)建的引用對象是在組件的閉包中存在的,而不是作為組件的狀態(tài)存在。所以即使組件卸載,引用對象仍然可以被訪問和修改。
個人理解,useRef創(chuàng)建的引用對象在遞歸方法中被引用,類似閉包的原理,所以在組件卸載的時候沒有被清理。(如果理解錯誤,歡迎指正,輕點噴??)
用途
我覺得在頁面請求完數(shù)據(jù)之后,需要對數(shù)據(jù)進行復雜遞歸處理的時候,又把頁面關閉,這種情況可能需要。
到此這篇關于詳解React組件卸載怎么中止遞歸方法的文章就介紹到這了,更多相關React中止遞歸方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
react使用antd的上傳組件實現(xiàn)文件表單一起提交功能(完整代碼)
最近在做一個后臺管理項目,涉及到react相關知識,項目需求需要在表單中帶附件提交,怎么實現(xiàn)這個功能呢?下面小編給大家?guī)砹藃eact使用antd的上傳組件實現(xiàn)文件表單一起提交功能,一起看看吧2021-06-06
React Native可定制底板組件Magic Sheet使用示例
這篇文章主要為大家介紹了React Native可定制的底板組件Magic Sheet使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
教你快速搭建 React Native 開發(fā)環(huán)境
這篇文章主要介紹了搭建 React Native 開發(fā)環(huán)境的詳細過程,本文通過圖文指令給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
React?Native系列之Recyclerlistview使用詳解
這篇文章主要為大家介紹了React?Native系列之Recyclerlistview使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
react-router-domV6版本的路由和嵌套路由寫法詳解
本文主要介紹了react-router-domV6版本的路由和嵌套路由寫法詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03

