R

React Handbook

Clean • Professional

React useEffect Hook: Manage Side Effects & Cleanup

3 minute

React useEffect Hook

In React, functional components do not have lifecycle methods like class components (componentDidMount, componentDidUpdate, componentWillUnmount). Instead, React provides the useEffect hook, which allows you to perform side effects in function components.

Side effects can include:

  • Fetching data from an API
  • Subscribing to events
  • Manipulating the DOM
  • Setting timers
  • Logging or analytics

What is useEffect?

The useEffect hook allows you to run code after React renders the component. It combines the functionality of multiple lifecycle methods into a single API for functional components.

Syntax:

useEffect(() => {
  // Your side effect code here
  return () => {
    // Optional cleanup code here
  };
}, [dependencies]);
  • The first argument is a function containing the effect.
  • The return function is optional and is used to clean up resources when the component unmounts or before the effect runs again.
  • The second argument is an array of dependencies that determine when the effect should run.

Example – Logging

import React, { useEffect } from "react";

function Logger() {
  useEffect(() => {
    console.log("Component rendered or updated!");
  });

  return <h1>Hello, React!</h1>;
}

export default Logger;

useEffect with Empty Dependency Array – Component Did Mount

If you want the effect to run only once (when the component mounts):

import React, { useEffect } from "react";

function App() {
  useEffect(() => {
    console.log("Component mounted!");

    // Cleanup on unmount
    return () => console.log("Component will unmount!");
  }, []); // Empty array = run only on mount

  return <h1>Hello, React!</h1>;
}

export default App;

useEffect with Dependencies – Component Did Update

When you want the effect to run only when certain variables change, include them in the dependency array:

import React, { useState, useEffect } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`Count changed: ${count}`);
  }, [count]); // Effect runs only when `count` changes

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Counter;

Cleanup Function – Cleaning Side Effects

The cleanup function prevents memory leaks by removing subscriptions, timers, or event listeners.

  • Cleanup is called before unmount or before the next effect execution if dependencies change.
import React, { useEffect } from "react";

function Timer() {
  useEffect(() => {
    const interval = setInterval(() => {
      console.log("Tick");
    }, 1000);

    return () => {
      clearInterval(interval); // Clean up interval on unmount
      console.log("Timer cleared");
    };
  }, []);

  return <h1>Timer is running...</h1>;
}

export default Timer;

Common useEffect Patterns

Fetching API Data

useEffect(() => {
  async function fetchData() {
    const response = await fetch("<https://api.example.com/data>");
    const data = await response.json();
    console.log(data);
  }
  fetchData();
}, []); // Runs once on mount

Listening to Events

useEffect(() => {
  function handleResize() {
    console.log("Window resized!");
  }
  window.addEventListener("resize", handleResize);

  return () => window.removeEventListener("resize", handleResize);
}, []); // Runs once on mount

Updating Document Title

useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]); // Runs whenever count changes

Rules of useEffect

  • Always call at the top level of the component (not inside loops or conditions).
  • Do not call conditionally inside blocks; use dependencies instead.
  • Dependencies must include all variables used in the effect to avoid stale values.

Why useEffect is Important?

  • Handles side effects in functional components
  • Combines mounting, updating, and unmounting behavior in a single hook
  • Prevents memory leaks with cleanup functions
  • Works with other hooks like useState and useReducer for dynamic UI

Article 0 of 0