【问题标题】:React setTimeout - memory leak反应 setTimeout - 内存泄漏
【发布时间】:2021-01-25 08:25:14
【问题描述】:

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

【问题讨论】:

  • 似乎Message 组件尝试自我更新,但组件被卸载。贴出Message在做什么的代码?
  • 是的,消息组件在其他地方也有使用。

标签: javascript reactjs memory-leaks


【解决方案1】:

嗯,这个错误其实很不言自明:setTimeout 触发的状态改变函数是在组件已经被卸载后调用的。但它是变相的无操作:组件不再被渲染,为什么有人会对它的内部状态变化感兴趣?

值得庆幸的是,React 提供了a documented way 来清理这些和类似的异步状态更改器——通过使用由useEffect 回调返回的函数。像这样:

useEffect(() => {
  const timeoutId = setTimeout(() => setVisible(false), 5000);
  return function cleanup() {
    clearTimeout(timeoutId);
  }
}, []);

请注意,函数不必命名(但它简化了一点阅读)。

【讨论】:

【解决方案2】:

您会收到该警告,因为您设置的计时器可能在组件从 DOM 卸载后被调用。

您需要从useEffect 挂钩中清除cleanup 回调 中的计时器:

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 也会清理 在运行下一个效果之前从上一个渲染中添加效果 时间。我们将讨论为什么这有助于避免错误以及如何选择退出 这种行为,以防它在下面产生性能问题。

【讨论】:

    猜你喜欢
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2014-06-07
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多