Do cleanup from useEffect in React.js whenever possible
The useEffect hook in React.js is the one that you would be using to run side effects for a particular component.
There’s a little issue with it though.
The problem
For instance, if you want to run some side-effects only once every time a component renders (or in other words when the component mounts), here’s how you can do it.
useEffect(() => {
// This runs only on mount (when the component appears)
}, []);
As you can tell, you would leave the dependency array empty in this case, and now anything inside this useEffect
would run only once every render.
This should work fine but consider the following scenario where you would render a dialog when the component renders.
Here’s how this would look like.
useEffect(() => {
const dialog = dialogRef.current;
dialog.showModal();
}, []);
You may think that this would work perfectly fine but let’s think about a situation where let’s say your app is a single-page application (SPA) and you navigate to the other page while the dialog is still open and come back once again to the same page.
In this case, the above useEffect
would run again and the <dialog>
element would throw an error since the previous instance of the dialog is still open.
The cleanup function
To mitigate this, we can write a cleanup function in this useEffect
that closes the dialog
instance.
Here’s how that would look like.
useEffect(() => {
const dialog = dialogRef.current;
dialog.showModal();
// the cleanup function
return () => dialog.close();
}, []);
The explanation
Since the cleanup function would run before running the actual useEffect
logic, it would first close the initial dialog instance and open a new instance of the dialog in situations where the useEffect
would run multiple times as I discussed previously.
Here’s the sequence of how things run.
- The
<dialog>
is opened - The
<dialog>
is closed through the cleanup function whenuseEffect
runs again - The
<dialog>
is opened afterward
Lastly, the cleanup function would run once again when the component unmounts (gets removed).
In closing
As you can tell, to prevent issues like this from arising, it’s always advisable to use the useEffect
hook with a cleanup function that would possibly negate the useEffect
upon remounting the component.
Like this article?
Buy me a coffee👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.