panzerdp / dmitripavlutin.com-comments

7 stars 0 forks source link

react-cleanup-async-effects/ #127

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

How to Cleanup Async Effects in React

How to correctly cleanup async side-effects in React when the component unmounts or updates.

https://dmitripavlutin.com/react-cleanup-async-effects/

kyldex commented 3 years ago

Hi, thanks for this great article. It seems that manual event listeners (i.e. non React events, or synthetic events) need to be cleaned up as well when the component unmounts. Built-in React listeners are cleaned up automatically, but it seems it's not the case for manual listeners. Do you implicitly recommend it in the 4.3 debounce and throttle section ?

realleyriley commented 2 years ago

Great information. Why is this an issue though? Setting a state on an unmounted component doesn't cause a memory leak does it? Why does react warn us about this?

panzerdp commented 2 years ago

Hi, thanks for this great article. It seems that manual event listeners (i.e. non React events, or synthetic events) need to be cleaned up as well when the component unmounts. Built-in React listeners are cleaned up automatically, but it seems it's not the case for manual listeners. Do you implicitly recommend it in the 4.3 debounce and throttle section ?

Yes, manually added listeners might need manual removal too.

panzerdp commented 2 years ago

Great information. Why is this an issue though? Setting a state on an unmounted component doesn't cause a memory leak does it? Why does react warn us about this?

Dispose resources when you don't need them.

gathrlabs commented 2 years ago

Hey Dmitri, this was an awesome article and I took a lot from it. I am hoping you might be able to point me in the right direction when it comes to timer functions.

  useEffect(() => {
    (async () => {
        let {
          status,
        } = await Location.requestForegroundPermissionsAsync();
        const intervalID = setInterval(async () => {
               // Every 10 seconds do something with user's location.
            });
        }, 10000);
        return () => { clearInterval(intervalID)};
        })();
     }, []);

I am attempting to use the above snippet, but for some reason the cleanup function is not being called. Is this because of some strange circumstance that happens with timer functions within an async useEffect()? Thanks for your help!

panzerdp commented 2 years ago

Hey Dmitri, this was an awesome article and I took a lot from it

Hi Tom (@gathrlabs) and thanks!

but for some reason the cleanup function is not being called

The problem is that you need to return the cleanup function from the direct callback of the useEffect(callback), but in your code it is returned from the async function.

Here's a possible fix:

useEffect(() => {
  let intervalID;
  (async () => {
    let {
      status
    } = await Location.requestForegroundPermissionsAsync();
    intervalID = setInterval(async () => {
      // Every 10 seconds do something with user's location.
    }, 10000);
  })();
  return () => {
    clearInterval(intervalID)
  };
}, []);
rromikas commented 2 years ago

This works. Thank you

rajnandani296 commented 2 years ago

Hello Dmitri, Can you please give me clean up fetch request when fetch request is done in another file.

rajnandani296 commented 2 years ago

Hello Dmitri Great Article, What about if setTimeout is not written inside useEffect how to clear timeout

yousexd commented 2 years ago

The codesandbox is no longer working.

panzerdp commented 2 years ago

The codesandbox is no longer working.

Thanks for letting me know. The demos have been fixed.