简体   繁体   中英

React setTimeout - memory leak

I have the below component, where i am displaying message for 5 sec and then removing it from home page.

when i switch between the pages, i'm getting below error sometimes. Any Advice please

    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.

Code:

 const Home = props => {
    
      const [visible, setVisible] = useState(true);
    
       useEffect(() => {
        setTimeout(() => setVisible(false), 5000);
      }, []); 
    
      return (
       <div >
         {visible && <Message showDefault={false}  /> }
         <BaseView  />
    
       </div> 
        
        );
    };

Well, the error is actually quite self-explanatory: the state-changing function triggered by setTimeout is invoked after the component has already been unmounted. But it's no-op in disguise: component is no longer rendered, why should anyone be interested in its internal state changes?

Thankfully, React provides a documented way to clean up those and similar async state-changers - by using a function returned by an useEffect callback. Like this:

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

Note that the function doesn't have to be named (but it simplifies reading a bit).

You get that warning as the timer you have setup might have been called after the component has been unmounted from the DOM.

You need to clear the timer in the cleanup callback from the useEffect hook:

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

From the 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM