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:
- Effect Callback: A function that contains the side effect logic.
- 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:
- We import
useState
anduseEffect
fromreact
. - The
users
state variable stores the fetched user data. - 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 (simulatingcomponentDidMount
behavior).
- The effect callback function fetches data from an API and updates the
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 tocomponentDidMount
). - 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