React Hooks - UseEffect

React Hooks - UseEffect

What is UseEffect?

Introduction

Hey guys, In our last article, we learnt about state(specifically useState) and also build a mini project. In this article, we’ll be talking about React hooks and talking more about the useEffect hook. Let’s dive right in 😉

What is useEffect?

useEffect is a React hook that enables you to perform side effects in functional components. Side effects are operations that affect the external world, such as data fetching, subscriptions, or manually changing the DOM. Unlike lifecycle methods in class components, useEffect allows you to manage side effects in a declarative and concise manner.

How does it work?

Basically, useEffect runs after the render is committed to the screen. It runs after every render by default.

Basic Syntax

Here is how the syntax of useEffect look like 👇🏽

import { useEffect } from 'react';

const useEffectSyntax = () => {
  useEffect(() => {
    // Your side effect code here
    return () => {
      // Cleanup code (optional)
    };
  }, [/* dependencies */]);

  // Component render logic
}
export default useEffectSyntax;
  • The first argument to useEffect is the function containing the side effect code. it is where the main logic of the code lives.

  • The second argument is an array of dependencies. When any of these dependencies change, the effect is re-run.

  • The return function (optional) is used for cleanup. It runs before the component unmounts or when the dependencies change.

Examples

Let’s see some basic examples to understand useEffect better;

import { useEffect } from 'react';

const SimpleEffectExample = () => {
  // useEffect to perform an action on component mount
  useEffect(() => {
    console.log('Component mounted!');

    // Cleanup function (optional)
    return () => {
      console.log('Component will unmount!');
    };
  }, []); // Empty dependency array means it runs only once on mount

  return (
    <div>
      <p>This is a simple component with useEffect.</p>
    </div>
  );
}

export default SimpleEffectExample;

From the example above, the useEffect is used to log messages to the console. The function inside it runs after the component is initially rendered. The dependency array [] is empty, meaning the effect runs only once when the component mounts. It simulates the behavior of componentDidMount in class components. Inside the useEffect function:

  • It logs 'Component mounted!' to the console.

  • It returns a cleanup function that logs 'Component will unmount!' to the console when the component is about to unmount.

Let’s see another example 👇🏽

import { useState, useEffect } from 'react';

const SimpleEffectExample = () => {
  // State to hold a count value
  const [count, setCount] = useState(0);

  // useEffect to update the document title
  useEffect(() => {
    document.title = `Count: ${count}`;

    // Cleanup function (optional)
    return () => {
      document.title = 'React App'; // Reset the title on component unmount
    };
  }, [count]); // Re-run effect when count changes

  return (
    <div>
      <p>Current Count: {count}</p>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>
        Increase Count
      </button>
    </div>
  );
}

export default SimpleEffectExample;

From the example above, we have a state variable count initialized to 0 using useState, and a button to increase the count. The useEffect is used to update the document title with the current count. It takes a function as its first argument, and this function will run after the component renders. The dependency array [count] specifies that the effect should re-run whenever the count state changes. Inside the useEffect function:

  • We set the document title to include the current count.

  • We return a cleanup function that resets the document title to 'React App' when the component unmounts or when count changes.

The component renders a paragraph displaying the current count and a button. When the button is clicked, the setCount function is called, updating the count state and triggering the useEffect to update the document title.

Let’s see one more example 👇🏽

import { useState, useEffect } from 'react';

const FetchData = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('<https://api.example.com/data>'); // just some dummy api endpoint
      const result = await response.json();
      setData(result);
    };

    fetchData();
  }, []); // Empty dependency array means it runs only once on mount

  return (
    <div>
      {data ? (
        <ul>
          {data.map(item => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}

This example is a bit more technical than the previous ones. but we’ll go through it together.

From the example above, we use the useState hook to create a state variable data and its corresponding updater function setData. The initial value of data is set to null.

Inside useEffect, an asynchronous function fetchData is declared. This function fetches data from a hypothetical API (https://api.example.com/data) using the fetch API.

The fetchData function is then invoked within the useEffect. Because the dependency array is empty ([]), this effect will run only once when the component mounts.

Once the data is fetched, it is stored in the data state using the setData function.

Conclusion

That’s all guys, Hope you learned something from this article, Remember that useEffect basically allows you to perform side effects. It’s perfectly fine if you don’t understand it at first. Just try to go over each of the examples.

Have an amazing weekend and see you next week 😀