DEV Community

Cover image for The Beginner's Guide to React's useEffect Hook
Louiza Mak
Louiza Mak

Posted on • Updated on

The Beginner's Guide to React's useEffect Hook

One of the core fundamentals beginner coders learn is that functions are "self-contained" blocks of reusable code that perform a single task. Functions "take in" data, processes it, and "return" a result, and can be run multiple times. But what if they could do more? What if they could have a side effect? Let me introduce React's useEffect hook.

Hooks

If you're new to React, like I was a month and a half ago, you might not be too familiar with hooks, yet. Hooks lets you add stateful logic to a functional component without writing a class. There are several types of hooks built into React including, but not limited to: Effect, Context, and State. useEffect falls under the Effect hook, hooks that allow components to connect and synchronize with external systems such as the browser DOM, network, and other non-React code.

Hook meme.

But why would we need to do that? In the realm of React development, managing side effects is an essential aspect of building robust and efficient applications. Here are a few examples for you. What if we have an object that we want to use to control a non-React component based on the object's State? Or what if we need to perform a GET request right after the page is fully rendered? How about setting up a timer that only increments while it is active? Or simply being able to subscribe to events or update the DOM? These scenarios, crucial for creating dynamic user interfaces, are easily achievable with the useEffect hook.

useEffect Basic Usage

Before we begin, don't forget to import the useEffect hook!

Now, let's start with the basics. The useEffect hook accepts two parameters: a callback function and an array of dependencies. The function is the side effect we want to perform, and the dependencies array allows us to specify values that, when changed, will trigger the effect to run again. This mechanism ensures precise control over when the side effect should be executed.

Basic template for the useEffect hook within a React component.

That is why understanding how dependencies work in useEffect is key for writing efficient and bug-free code. When we provide a dependency array, React will re-run the effect whenever any of the dependencies change. If you omit the dependency array, the effect will run on every render, potentially causing performance issues. Imagine the side effect code running in an infinite loop, an unstoppable force littering your console with lines of GET request arrays or "Hello, World!". Scary. That's why, at the minimum, we should always supply the useEffect hook with an empty dependency array. We can also provide arrays that aren't empty, and these will ensure that the effect will only run when the contents of the array change.

Basic template of useEffect hook showing off the dependencies array.

If we provide multiple arrays, such as dependency1 and dependency2, the effect will read this as run when dependency1 or dependency2 changes. And these arrays usually change when we setState of a component and it re-renders. By default useEffect will run the side effect function in the following order:

useEffect hook flow chart.

By following these dependency array rules, we can optimize performance and avoid unnecessary computations.

Cleaning Up

Another neat feature of the useEffect hook is that it is designed to allow the 'return' of a function within it as a means to tidy up our code before the component unmounts. This function also runs right before the execution of the next effect. This is because specific side effects might require cleanup to prevent memory leaks or unwanted behavior.

Clean up meme

For example, let's say you're performing a fetch request on the server to get user A's information but change your mind before the request is complete. Instead, you decide to fetch the information of user B. Without the cleanup function, both fetch requests would continue to run even though the components have been unmounted or the dependencies have changed. This can lead to unexpected behaviors such as the effect attempting to update components that are no longer mounted or display the wrong information. With the cleanup function, we can abort the first fetch request of user A before moving on to user B and ensure that resources are properly released when they're no longer needed.

The following is another example with corresponding code:

use-Effect-Cleanup-Code.png

In this example, the useEffect hook sets up an interval that increments count every second. The clean-up function returned by useEffect clears the interval using `clearInterval(intervalID) which stops the interval from running.

Conclusion

In conclusion, the useEffect hook is an incredibly essential tool for managing side effects in React functional components. It's versatile and simple and can handle a wide range of scenarios such as fetching data, subscribing to events, and interacting with the DOM. Although we shouldn't use this effect to handle every aspect of our code like orchestrating the data flow of our apps, it is a great hook that lets us "step out" of our React code and synchronize with external systems like API's, databases, networks, and so on. So go ahead, leverage the power of useEffect for your projects, and embrace this wonderful React hook.

Top comments (2)

Collapse
 
in43sh profile image
Sergey Sherstobitov

Hi, thank you for the post! Can you explain "Cleaning Up" part more? Can you provide some examples? Does it mean that you need to do it every time you use useEffect()? Maybe you could do a separate post about it.
Also, nice memes

Collapse
 
louizamak profile image
Louiza Mak

Definitely! I'll be revisiting this post in the coming days to expand on that section and provide an example!
The cleanup function is optional to include in your useEffect callback function block; however, it is recommended to avoid things like memory leaks. If you do include the cleanup function, it will run every time useEffect runs.