Introduction
useEffect is one of the most powerful — and most misunderstood — hooks in React.
Many developers use it by copying snippets from the internet without fully understanding
when it runs and why it exists.
In this guide, you will learn React useEffect in a clear and practical way, with real-world examples and common mistakes explained simply.
What Is useEffect?
useEffect is a React hook that allows you to run code
after a component renders.
It is designed specifically for handling side effects such as:
- Fetching data from an API
- Subscribing to events or sockets
- Updating the DOM manually
- Running timers or intervals
Side effects are operations that happen outside the normal rendering flow of React.
Basic useEffect Example
Here is the simplest form of useEffect:
import { useEffect } from "react";
useEffect(() => {
console.log("Component rendered");
});
This effect runs after every render — including the initial render and every re-render caused by state or props changes.
The Dependency Array Explained
The dependency array controls when the effect should re-run.
Run Only Once (On Mount)
useEffect(() => {
console.log("Runs only once");
}, []);
An empty dependency array tells React: “Run this effect only after the first render.”
This pattern is commonly used for:
- Initial data fetching
- Analytics tracking
- Setting up subscriptions
Run When a Value Changes
useEffect(() => {
console.log("Runs when count changes");
}, [count]);
This effect runs:
- After the first render
- Whenever
countchanges
React compares dependency values using strict equality (===).
Cleanup Function in useEffect
Some side effects require cleanup — such as intervals, event listeners, or subscriptions.
To clean up an effect, return a function from useEffect.
useEffect(() => {
const interval = setInterval(() => {
console.log("Running...");
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
The cleanup function runs:
- Before the component unmounts
- Before the effect re-runs (if dependencies change)
Common useEffect Mistakes
Many bugs in React applications come from incorrect use of useEffect.
1. Forgetting the Dependency Array
Without a dependency array, the effect runs after every render — which may cause performance issues or infinite loops.
2. Overusing useEffect
Not everything belongs inside useEffect.
Pure calculations should be done directly during render or using useMemo.
3. Putting Non-Side-Effect Logic Inside useEffect
useEffect should not be used for logic that determines what to render.
That logic belongs in the component body.
When You Should Use useEffect
Use useEffect only when you need to:
- Interact with external systems
- Synchronize state with something outside React
- Perform side effects after rendering
If you are unsure whether you need useEffect,
chances are — you probably don’t.
Final Thoughts
useEffect becomes much easier once you understand:
- When React renders
- What counts as a side effect
- How dependency arrays work
Mastering useEffect will help you write cleaner, more predictable
React applications.
Take time to experiment, read your code carefully, and avoid copying patterns you don’t fully understand.