React Side Effects Explained with useEffect (2025 Guide)
October 1, 2022
In React, side effects are actions that occur outside the normal rendering process. Examples include fetching data, updating the DOM directly, working with APIs, or syncing with browser storage. React provides the useEffect hook to handle these tasks.
When Does React Run useEffect?
- On mount (first render).
- On updates (when dependencies change).
- On unmount (cleanup).
React does not run useEffect on the server in Server Components — it only runs in the browser after render.
The Dependency Array
The second argument to useEffect is the dependency array.
[]→ Run only once after mount.[value]→ Run whenvaluechanges.- Omit it → Run after every render.
Example: useEffect with State Dependency
import React, { useState, useEffect } from "react";
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
return () => {
document.title = "React App";
};
}, [count]); // effect runs whenever "count" changes
return (
<button onClick={() => setCount(count + 1)}>
Increase Count ({count})
</button>
);
}
Side Effect Examples
- API calls (fetching data)
- WebSockets (listening to live updates)
- Local Storage (persisting state)
- Syncing multiple states
Best Practices (2025)
- Always declare dependencies (use ESLint plugin
react-hooks/exhaustive-deps). - Clean up effects when possible (
return () => { ... }). - Avoid heavy computations inside
useEffect→ use memoization instead. - For async logic, use an async function inside
useEffect.
useEffect(() => {
let isActive = true;
async function fetchData() {
const res = await fetch("/api/data");
if (isActive) {
// only update if still mounted
}
}
fetchData();
return () => {
isActive = false;
};
}, []);
Conclusion
useEffect is the cornerstone of managing side effects in React functional components. By mastering dependency arrays, cleanup functions, and modern patterns, you’ll write React apps that are predictable, performant, and easier to maintain.