Skip to main content

useEffect

The useEffect Hook is a versatile tool in React that allows you to perform side effects within functional components. Side effects encompass actions that interact with external data sources, subscriptions, timers, or anything that affects the component beyond its render output.

Why Use useEffect?

  • Data Fetching: Fetch data from APIs or other external sources to populate the UI.
  • Subscriptions: Subscribe to external data sources like WebSockets or event emitters to update the UI based on changes.
  • Timers: Create timers or delays that trigger actions within the component.
  • Cleanup: Perform cleanup actions (like unsubscribing from data sources) when a component unmounts.

Understanding useEffect

  • Function: It's a Hook imported from react.
  • Side Effects: It allows you to perform side effects within functional components.
  • Arguments: It takes two arguments:
    1. Effect Callback: A function that contains the side effect logic.
    2. Dependency Array (Optional): An optional array of values that determine when the effect runs.

Example (Data Fetching):

import { useState, useEffect } from 'react';

function UserList() {
const [users, setUsers] = useState([]);

useEffect(() => {
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => setUsers(data));
}, []); // Empty dependency array ensures effect runs only once on mount

return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}

Explanation:

  1. We import useState and useEffect from react.
  2. The users state variable stores the fetched user data.
  3. The useEffect Hook:
    • The effect callback function fetches data from an API and updates the users state.
    • The empty dependency array [] ensures the effect runs only once after the component mounts (simulating componentDidMount behavior).

Dependency Array and Effect Timing

The dependency array in useEffect controls when the effect runs:

  • Empty Array ([]): The effect runs only once after the initial render (similar to componentDidMount).
  • No Dependency Array (undefined): The effect runs after every render (similar to, but not exactly the same as, componentDidUpdate). This is generally discouraged due to performance implications.
  • Array with Values: The effect runs whenever any of the values in the dependency array change.

Example (Effect Running on State Change):

import { useState, useEffect } from 'react';

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

useEffect(() => {
console.log('Count changed:', count);
}, [count]); // Dependency array includes count

const handleClick = () => {
setCount(count + 1);
};

return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
}

In this example, the effect runs whenever the count state changes, logging the updated value to the console.

Cleanup Function (Optional)

The effect callback can optionally return a cleanup function. This function is executed before the component unmounts (similar to componentWillUnmount). It's useful for cleaning up resources like subscriptions or timers.

Example (Cleanup Function):

useEffect(() => {
const subscription = someDataSouce.subscribe(() => {
// Update UI based on data
});

return () => subscription.unsubscribe(); // Cleanup function
}, []); // Empty dependency array