反应setTimeout-内存泄漏

时间:2020-10-10 13:19:07

标签: javascript reactjs memory-leaks

我具有以下组件,在其中显示消息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> 
        
        );
    };

2 个答案:

答案 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也可以清理的原因 从上一个渲染中调高效果,然后再运行下一个效果 时间。我们将讨论为什么这有助于避免错误以及如何选择退出 如果稍后在下面会导致性能问题,则会出现这种情况。