The useEffect
hook in React allows you to perform side effects in function components. It is the combination of componentDidMount
, componentDidUpdate
, and componentWillUnmount
lifecycle methods from class components. Side effects can include data fetching, subscriptions, or manually changing the DOM.
Basic Usage
The useEffect
hook takes a function as its first argument and an optional dependency array as its second argument.
import React, { useState, useEffect } from 'react';
export default function ExampleComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
Dependencies
The dependency array tells React when to re-run the effect. If it’s empty ([]
), the effect runs only once after the initial render.
useEffect(() => {
// Effect logic here
}, []); // This effect runs only once
Data Fetching
You can use useEffect
to fetch data from an API when the component mounts.
import React, { useState, useEffect } from 'react';
export default function DataFetchingComponent() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://api.example.com/data')
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, []); // Empty array means this effect runs once
if (loading) {
return <div>Loading...</div>;
}
return (
<div>
<h1>Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
Effect Dependencies
The dependency array is crucial for optimizing performance and avoiding unnecessary effect runs. If any value in the dependency array changes, the effect will run again.
import React, { useState, useEffect } from 'react';
export default function DependencyComponent({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`https://api.example.com/users/${userId}`)
.then((response) => response.json())
.then((data) => setUser(data));
}, [userId]); // Effect re-runs whenever userId changes
if (!user) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}