React useEffect — Explained
What is useEffect?
It’s a React Hook that lets you run side effects in a function component. Side effects include things like:
- Fetching data from an API
- Setting up subscriptions or event listeners
- Updating the DOM directly
- Starting/stopping timers
Why do we need it?
Without useEffect, every render is just a pure function of props + state.
But in real apps, we often need to "do something" after a render — that’s where
useEffect comes in.
How it works
useEffect(() => {
// This is your effect (side effect code).
console.log("Component rendered or updated!");
// Optional cleanup function:
return () => {
console.log("Cleanup before the next effect or when unmounting");
};
}, [dependencies]);
The Dependency Array
-
No dependencies:
useEffect(() => { console.log("Runs after EVERY render"); }); -
Empty array
[]:useEffect(() => { console.log("Runs only once (like componentDidMount)"); }, []); -
With dependencies:
useEffect(() => { console.log("Runs when 'count' changes"); }, [count]);
Cleanup
useEffect(() => {
const timer = setInterval(() => {
console.log("Tick");
}, 1000);
return () => clearInterval(timer); // cleanup on unmount or before re-running
}, []);
Lifecycle Comparison
useEffect(..., [])≈componentDidMountuseEffect(..., [x])≈componentDidUpdate(for thatx)- Cleanup function ≈
componentWillUnmount
Example: Fetching Data
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(r => r.json())
.then(data => setUsers(data));
}, []); // only once
return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
);
}
Example: useEffect with a Dependency
In this example, the effect depends on count. It runs after the first render
and again whenever count changes.
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Count changed:", count);
document.title = `Clicked ${count} times`;
}, [count]); // <-- dependency array
return (
<div>
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
</div>
);
}
Example: useEffect with Multiple Dependencies
You can list more than one dependency. In this example, the effect runs when
either count or name changes.
function UserInfo() {
const [count, setCount] = useState(0);
const [name, setName] = useState("Alice");
useEffect(() => {
console.log(`Name: ${name}, Count: ${count}`);
document.title = `${name} clicked ${count} times`;
}, [name, count]); // <-- multiple dependencies
return (
<div>
<p>Hello {name}! You clicked {count} times.</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setName("Bob")}>Change Name</button>
</div>
);
}
Summary
useEffect= "Do something after render."- The dependency array controls when.
- Cleanup prevents leaks or unwanted duplication.

















