The beautiful useEffect React Hook

useEffect is for side effects
useEffect is to functional components what componentDidMount
, componentDidUpdate
, and componentWillUnmount
are, combined, to class components. It is a method responsible for all the so-called side effects that occur during the lifecycle of a React component.
Whether you want to make a call to an API, manipulate the DOM, or set up a subscription to sockets, useEffect is where all of that should take place.
useEffect is invoked on every render
Every single time your component re-renders, the useEffect hook is invoked anew. But what if you don’t want that to happen? What if you want to skip effects?
You can achieve that by instructing React to watch if certain values have changed between re-renders.
useEffect(() => {}, [dependencies]);
The first argument to the useEffect method is the function to execute. The second argument is the dependency array. This is key to skipping effects.
The dependency array
On every render, React takes a look at the dependency array, and compares it to the one from the previous render. If at least one of the elements in the array has changed, React will execute the effect again. If no element has changed, React skips the effect.
Usually, props or state go in the dependency array. Sometimes functions too. Anything the process depends on should be included in the dependency array.
If you want the effect to run only once, set the second argument of useEffect as an empty array[]
. This tells React that the effect does not depend on any values. That it should be run a single time, on the very first render of the component.
useEffect(() => {
// something here
},[]);
Don’t forget to clean-up after yourself
Once side-effects such as manipulating the DOM, or subscribing to sockets are carried out, it is imperative to clean-up after yourself by unsubscribing to avoid any unintentional memory leaks!
When you add a click event listener to a DOM element, you should remove the event listener after the lifecycle of the component ends. After the component disappears, a socket connection remains active. You must disconnect from the socket.
The clean-up is accomplished via the return function in useEffect. React will run it when the component disappears from the DOM.
When the component lifecycle ends, React will call the return function both to remove the event listener and to close the socket connection.
Conclusion
useEffect is so flexible. If you need to run an effect once on the first render, no problem. If you need to run the effect sometimes, but skip it on other occasions, no problem as well. If you need to run it all the time, no questions asked. It is also very convenient to ensure clean-up within the same useEffect hook, rather than writing a separate extra method.
I believe the above information is enough to comfortably employ the useEffect hook in your React code. If you want a deep dive into useEffect consider this incredible piece by Dan Abramov.