In React, side effects are operations that affect things outside the component or need to happen after rendering. Examples include:
- Fetching data from APIs
- Subscribing to events (WebSocket, scroll, timers)
- Manipulating the DOM directly
- Logging or analytics
React handles side effects primarily using the useEffect hook.
1️⃣ Using useEffect
import React, { useState, useEffect } from "react";
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
// Side effect: fetch data
fetch("https://api.example.com/users")
.then((res) => res.json())
.then((data) => setUsers(data));
// Optional cleanup function
return () => {
console.log("Cleanup if needed (unsubscribe, clear timers)");
};
}, []); // Empty dependency array → runs once after mount
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
);
}
Explanation:
useEffectruns after the component renders- Can return a cleanup function to clean resources when component unmounts
- Dependency array
[]controls when effect runs
2️⃣ Dependency Array
| Dependency Array | When useEffect Runs |
|---|---|
[] |
Only on mount |
[var1, var2] |
When var1 or var2 changes |
| No array | Runs after every render |
3️⃣ Common Patterns for Side Effects
- Data fetching
useEffect(() => {
const fetchData = async () => {
const res = await fetch("/api/data");
const data = await res.json();
setData(data);
};
fetchData();
}, []);
- Subscriptions / Event listeners
useEffect(() => {
const handleScroll = () => console.log(window.scrollY);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
- Timers
useEffect(() => {
const interval = setInterval(() => console.log("tick"), 1000);
return () => clearInterval(interval);
}, []);
⚡ In short:
Side effects in React are handled using
useEffect, which runs code after rendering. Always include a cleanup function for subscriptions, timers, or event listeners to avoid memory leaks and unexpected behavior.