我具有以下组件,在其中显示消息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>
);
};
答案 0 :(得分:2)
好吧,该错误实际上是不言自明的:由setTimeout
触发的状态更改功能在组件已卸载后被调用。但这不是伪装:不再渲染组件,为什么任何人都应该对其内部状态变化感兴趣?
感谢,React提供了a documented way来清理那些和类似的异步状态更改器-通过使用useEffect
回调返回的函数。像这样:
useEffect(() => {
const timeoutId = setTimeout(() => setVisible(false), 5000);
return function cleanup() {
clearTimeout(timeoutId);
}
}, []);
请注意,该函数不必命名(但是可以简化读取)。
答案 1 :(得分:2)
您会收到该警告,因为从DOM卸载组件后,可能会调用您已设置的计时器。
您需要从useEffect
钩清除<em>清理回调中的计时器:
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 docs:
为什么我们从效果中返回一个函数?这是可选的 清理机制的效果。每个效果都可能返回一个函数 之后清理。这样我们就可以保持添加和 删除彼此接近的订阅。他们是同一部分的一部分 效果!
React何时确切地清除效果? React执行清理 组件卸载时。但是,正如我们之前所了解的,效果 为每个渲染运行,而不仅仅是一次。这就是为什么React也可以清理的原因 从上一个渲染中调高效果,然后再运行下一个效果 时间。我们将讨论为什么这有助于避免错误以及如何选择退出 如果稍后在下面会导致性能问题,则会出现这种情况。