React useEffect Hook

The useEffect hook is one of the most powerful hooks in React. It allows you to perform side effects in functional components, such as fetching data, subscribing to events, or directly interacting with the DOM. By using useEffect, you can mimic lifecycle methods from class components, such as componentDidMount, componentDidUpdate, and componentWillUnmount.


1. Basic Example: Logging to the Console using useEffect Hook

In this example, we use useEffect to log a message to the console whenever the component renders. This demonstrates how the hook works by default, running after every render.

</>
Copy
import React, { useEffect } from 'react';

function Logger() {
  useEffect(() => {
    console.log('Component has rendered.');
  });

  return <h2>Check the console for messages!</h2>;
}

export default Logger;

Explanation:

  • useEffect: Executes the provided function after every render of the component. Reference: React useEffect Hook
  • This example logs a message to the console to demonstrate how useEffect works by default.

Output:

Basic Example for using useEffect Hook

2. Fetching Data using useEffect Hook

In this example, we use useEffect to fetch data from an API when the component mounts. The hook ensures that the data is fetched only once, mimicking the behavior of componentDidMount.

</>
Copy
import React, { useState, useEffect } from 'react';

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

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(json => setData(json));
  }, []); // Empty dependency array ensures this runs only once

  return (
    <div>
      <h2>Fetched Data:</h2>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default FetchData;

Explanation:

  • useState: Manages the state variable data, which stores the fetched API data.
  • useEffect: Executes the fetch call when the component mounts.
  • The empty dependency array [] ensures the fetch happens only once, similar to componentDidMount.

Output:


3. Timer with Cleanup using useEffect Hook

In this example, we use useEffect to set up a timer that updates every second. The hook includes a cleanup function to clear the timer when the component unmounts.

</>
Copy
import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);

    return () => clearInterval(interval); // Cleanup on unmount
  }, []);

  return <h2>Elapsed Time: {seconds} seconds</h2>;
}

export default Timer;

Explanation:

  • useState: Manages the state variable seconds, which tracks elapsed time.
  • useEffect: Sets up a timer when the component mounts.
  • The cleanup function clears the timer to prevent memory leaks when the component unmounts.

Output:


4. Dependency Array with useEffect

In this example, we demonstrate how the dependency array controls when useEffect is triggered. The effect runs only when the specified dependencies change.

</>
Copy
import React, { useState, useEffect } from 'react';

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

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

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

export default DependentEffect;

Explanation:

  • useState: Manages the state variable count.
  • useEffect: Logs a message to the console only when count changes.
  • The dependency array [count] ensures the effect is triggered selectively.

Output:


5. Combining Multiple Effects with Multiple useEffect Hooks

In this example, we use multiple useEffect hooks to handle different effects within the same component. Each hook is independent and runs based on its own dependencies.

</>
Copy
import React, { useState, useEffect } from 'react';

function MultiEffect() {
  const [count, setCount] = useState(0);
  const [message, setMessage] = useState('');

  useEffect(() => {
    console.log(`Count updated: ${count}`);
  }, [count]);

  useEffect(() => {
    console.log(`Message updated: ${message}`);
  }, [message]);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <br />
      <input type="text" value={message} onChange={e => setMessage(e.target.value)} placeholder="Enter a message" />
    </div>
  );
}

export default MultiEffect;

Explanation:

  • Two separate useEffect hooks manage different effects.
  • Each hook runs independently based on its dependency array.
  • This structure keeps effects focused and avoids unnecessary re-renders.

Output:


Conclusion

The useEffect hook is a versatile tool for managing side effects in React components. By understanding how to use the dependency array and cleanup functions, you can build efficient and predictable applications. Start experimenting with useEffect to handle side effects in your React projects!