反应 setTimeout - 内存泄漏

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> 
        
        );
    };

嗯,错误其实很self-explanatory:setTimeout触发的state-changing函数是在组件已经卸载后调用的。但它是 no-op 变相的:组件不再被渲染,为什么有人会对它的内部状态变化感兴趣?

幸运的是,React 提供了 a documented way 来清理那些和类似的异步 state-changers - 通过使用 useEffect 回调返回的函数。像这样:

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

请注意,该函数不必命名(但它可以简化阅读)。

您收到该警告是因为您设置的计时器可能在组件从 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

Why did we return a function from our effect? This is the optional cleanup mechanism for effects. Every effect may return a function that cleans up after it. This lets us keep the logic for adding and removing subscriptions close to each other. They’re part of the same effect!

When exactly does React clean up an effect? React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React also cleans up effects from the previous render before running the effects next time. We’ll discuss why this helps avoid bugs and how to opt out of this behavior in case it creates performance issues later below.