[英]React setTimeout - memory leak
我有以下組件,我在其中顯示消息 5 秒,然后將其從主頁中刪除。
當我在頁面之間切換時,有時會出現以下錯誤。 任何建議請
index.js:1 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.
代碼:
const Home = props => {
const [visible, setVisible] = useState(true);
useEffect(() => {
setTimeout(() => setVisible(false), 5000);
}, []);
return (
<div >
{visible && <Message showDefault={false} /> }
<BaseView />
</div>
);
};
好吧,這個錯誤實際上是不言自明的:在組件已經被卸載后調用由setTimeout
觸發的狀態改變 function。 但它是變相的空操作:組件不再被渲染,為什么有人會對它的內部 state 變化感興趣?
值得慶幸的是,React 提供了一種記錄在案的方法來清理這些和類似的異步狀態更改器——通過使用useEffect
回調返回的 function。 像這樣:
useEffect(() => {
const timeoutId = setTimeout(() => setVisible(false), 5000);
return function cleanup() {
clearTimeout(timeoutId);
}
}, []);
請注意,不必命名 function(但它可以簡化閱讀)。
您會收到該警告,因為您設置的計時器可能在組件從 DOM 卸載后被調用。
您需要在useEffect
掛鈎的清理回調中清除計時器:
const Home = props => {
const [visible, setVisible] = useState(true);
useEffect(() => {
const timerId = setTimeout(() => setVisible(false), 5000);
//Use the clean up callback which would be executed weh the component is unmounted
return () => clearTimeout(timerId);
}, []);
return (
<div >
{visible && <Message showDefault={false} /> }
<BaseView/>
</div>
);
};
來自React 文檔:
為什么我們從效果中返回 function? 這是效果的可選清理機制。 每個效果都可能返回一個 function,它會在它之后進行清理。 這讓我們可以讓添加和刪除訂閱的邏輯彼此靠近。 它們是相同效果的一部分!
React 到底什么時候清理效果? React 在組件卸載時執行清理。 然而,正如我們之前了解到的,效果會在每次渲染時運行,而不僅僅是一次。 這就是為什么 React 還會在下次運行效果之前清理上一次渲染的效果。 我們將在下面討論為什么這有助於避免錯誤以及如何選擇退出此行為以防它造成性能問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.