[英]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.