React.useEffect(): The Ultimate Guide to Managing Side Effects in Functional Components

Are you a React developer struggling to wrap your head around the useEffect hook? You're not alone! Despite its popularity, this hook can be tricky to use correctly and efficiently. But fear not! In this post, we'll dive deep into the useEffect hook and explore all the different ways react can help us perform side effects within our components. By the end of this post, you'll have a solid understanding of how to use useEffect to make your component reliable, testable, and predictable.

useEffect is a react hook that enables us to perform side effects within a functional component. To better understand side effects, we first need to grasp the concept of pure functions. Pure functions are functions that have no side effects, they always return the same output for the same input. As a result, pure functions are predictable, easier to test and less error-prone.

In the context of React, components are simply functions that take props as input and return JSX as output. However, components can have side effects if they perform any actions that are not related to rendering output. These side effects can include making API calls, updating the DOM, or using timer functions like setTimeOut or setInterval. When a component has side effects it can be harder to understand what this component is doing and how it is interacting with other components.

This is where useEffect comes in handy, it manages side effects in a controlled way. For example, suppose that you have a component that needs to fetch data from an API when it first mounts. Without using useEffect you might perform the API call in the body of your components, which would cause it to be called every time the component is rendered, leading to unnecessary API calls. By using useEffect with an empty dependency array, you can ensure that the API call is only made once when the component is mounted. By encapsulating side effects within useEffect hook, you can make it more clear what side effects a component has and when they occur.

The syntax of useEffect is straightforward. It takes two parameters:

  1. A required call-back function, which will be called after the component renders.

  2. An optional array, called The dependencies array. This array should include all the values that our side effects rely upon.

useEffect(() => {
  //
}, []);

useEffect will check and see if values within the array have changed between renders, if so it will run our function again.

useEffect will run automatically on the initial render (when the component first mounts on the page). If we want useEffect to run only on the initial render, we provide it with a callback and an empty array. However, if we don't provide a dependencies array at all, the callback function will be rendered after each render, which may cause errors if we are updating state within the useEffect. This is because the default behavior of React is to re-render the component and all its children after a state update. Since the useEffect runs after every single render, this will lead to an infinite loop.

What is useEffect cleanup?

Cleanup refers to canceling the side effect when the component unmounts (disappears from the page, for example, when we navigate to another page). Cleanup helps us avoid memory leaks. For instance, when you use a timer function like setInterval to run code every second, that code will continue running even after you unmount the component. To do a cleanup, all you need is to return a function that will cancel the side effect. That function will run automatically when the lifecycle of that component ends (when the component unmounts).

 useEffect(() => {

    const intervalId = setInterval(()=>{
    //  code
    }, 1000) // run every second

   return () => {
    // Side Effects Cleanup
       clearInterval(intervalId)
    }
}, []);

Conclusion:

In conclusion, useEffect is a powerful hook that helps us manage side effects in React functional components. It allows us to perform side effects in a controlled way and clean them up when necessary. By using useEffect, we can make our code more predictable, easier to test, and less prone to errors.

1
Subscribe to my newsletter

Read articles from Mohamed Abdellahi Haibelty directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mohamed Abdellahi Haibelty
Mohamed Abdellahi Haibelty

Junior software developer | passionate about diving deeper into the world of React.