If you are learning React, chances are useEffect confused you at least once.
Questions like:
- Why does useEffect run twice?
- When should I use it?
- What is dependency array?
- How is it different from lifecycle methods?
Don’t worry.
In this post, I’ll explain useEffect in the simplest way possible, using real-world analogies and clear examples.
What is useEffect in React?
👉 useEffect is used to perform side effects in React components.
Side effects include:
- Fetching data from an API
- Updating the DOM
- Setting timers
- Subscribing to events
- Logging data
Simply put:
useEffect runs code when something changes in your component.
Basic Syntax of useEffect
useEffect(() => {
// side effect code
}, []);
It has two parts:
- Effect function – what you want to do
- Dependency array – when you want to do it
Case 1: useEffect Without Dependency Array
useEffect(() => {
console.log("Component rendered");
});
What happens?
✅ Runs after every render
⚠️ Usually not recommended, can cause performance issues.
Case 2: useEffect With Empty Dependency Array []
useEffect(() => {
console.log("Component mounted");
}, []);
What happens?
✅ Runs only once, after first render
Equivalent to:
componentDidMount()
👉 Most common use case: API calls
Example: Fetching Data
useEffect(() => {
fetch("/api/users")
.then(res => res.json())
.then(data => setUsers(data));
}, []);
✔️ Fetches data only once
✔️ Avoids infinite loops
Case 3: useEffect With Dependencies
useEffect(() => {
console.log("Count changed");
}, [count]);
What happens?
✅ Runs only when count changes
👉 Useful for reacting to state or prop changes
Example: Search Input
useEffect(() => {
fetchResults(searchText);
}, [searchText]);
✔️ Runs only when user types
✔️ Optimized & efficient
Cleanup Function in useEffect 🧹
Some effects need cleanup.
Example:
- Timers
- Event listeners
- Subscriptions
useEffect(() => {
const timer = setInterval(() => {
console.log("Running...");
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
👉 Cleanup runs when:
- Component unmounts
- Dependencies change
Why Does useEffect Run Twice in React?
In React Strict Mode (development):
- React runs effects twice
- This helps detect bugs
🚨 It does NOT happen in production
Common Mistakes with useEffect ❌
❌ Missing dependency array
useEffect(() => {
setCount(count + 1);
});
➡️ Causes infinite loop
❌ Incorrect dependencies
useEffect(() => {
fetchData();
}, []);
But fetchData uses props/state → bug!
When Should You Use useEffect?
Use useEffect when:
✅ You interact with outside world
✅ You perform side effects
❌ Not for simple calculations
Summary Table 📌
| Scenario | Dependency |
|---|---|
| Run once | [] |
| Run on every render | No array |
| Run on change | [state/props] |
| Cleanup needed | return () => {} |
Final Thoughts
If you remember just one line, remember this:
useEffect syncs your React component with the outside world.
Mastering useEffect will:
- Improve performance
- Prevent bugs
- Make you a better React developer