Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 30, 2020 04:35 pm GMT

An elegant solution for memory leaks in React

Cover image from Valentin Petkov from Unsplash

An elegant solution for memory leaks in React

When working with asynchronous calls, for example API calls, you might have encountered this error :

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.

A GIF is worth a thousand words ...

A GIF showing a component that is being unmounted while it was performing some asynchronous logic

This is a small page that simulates some asynchronous logic on load, and then updates the view accordingly. Here, I unmount the component before the async work has been finished, and trigger the Error. (I took this example from this StackOverFlow post)

This is caused by this code :

function Example() {  const [text, setText] = useState("waiting...");  useEffect(() => {    simulateSlowNetworkRequest().then(() => {      setText("done!"); //  what if the component is no longer mounted ?      // => Warning: Can't perform a React state update on an unmounted component.    });  }, []);  return <h2>{text}</h2>;}

When running into that issue, I found multiple solutions, the most used one seems to be this one :

function OtherExample() {    const [text, setText] = useState("waiting...");  useEffect(() => {    let isMounted = true; //     simulateSlowNetworkRequest().then(() => {      if (!isMounted) { //         setText("done!"); // no more error      }    });    return () => {      isMounted = false; //     };  }, []);  return <h2>{text}</h2>;}

But it requires you to add quite a lot of stuff into your component, having to deal with that isMounted variable all over the place ...

There are other interesting solutions, like making your Promises cancellable :

You told me there would be an elegant solution !

I wasn't lying! The solution I came up with is a very simple hook. It works just like React's useState, but it basically checks if the component is mounted before updating the state !

Here is an example of the refactored code :

function OtherExample() {  const [text, setText] = useStateIfMounted("waiting..."); //   React.useEffect(() => {    simulateSlowNetworkRequest().then(() => {      setText("done!"); // no more error    });  }, [setText]);  return <h2>{text}</h2>;}

Here is the CodeSandBox if you wanna play around !

TLDR

Use useStateIfMounted hook, that will only update the state if your component is mounted !

I hope this might be helpful, feel free to reach me out in any case !


Original Link: https://dev.to/nans/an-elegant-solution-for-memory-leaks-in-react-1hol

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To