What is useEffect in React?

Learn React useEffect with practical examples. Understand side effects, dependency arrays, cleanup functions, API requests, and React best practices.
React useEffect Hook Explained: Managing Side Effects in React
As React applications grow, components often need to do more than simply render UI.
For example:
- fetch data from an API
- update the page title
- start timers
- listen for window events
- synchronize data with external systems
These tasks are known as side effects .
React provides the useEffect Hook to handle side effects inside functional components.
The useEffect Hook is one of the most commonly used Hooks in React and is essential for building real-world applications.
In this guide, you'll learn what useEffect is, how it works, and how developers use it in production React applications.
Prerequisites
Before learning useEffect, make sure you understand:
These concepts will help you understand how useEffect works.
What is useEffect?
The useEffect Hook allows React components to perform side effects.
Basic syntax:
useEffect(() => {
// Side Effect Logic
}, []);
The Hook runs code after React renders the component.
What Are Side Effects?
A side effect is anything that interacts with the outside world or performs actions beyond rendering UI.
Examples:
- API requests
- localStorage operations
- timers
- event listeners
- updating the document title
- WebSocket connections
These operations should not run directly inside component rendering logic.
Why Do We Need useEffect?
Consider this example:
function App() {
fetch("/api/users");
return <h1>Hello</h1>;
}
This fetch request executes every time the component renders.
This can cause:
- unnecessary API calls
- performance issues
- unexpected behavior
Instead, use:
useEffect(() => {
fetch("/api/users");
}, []);
Now the request runs only when intended.
Importing useEffect
Before using it, import the Hook.
import { useEffect } from "react";
Running useEffect Once
Example:
useEffect(() => {
console.log("Component Mounted");
}, []);
The empty dependency array means:
Run only once
after initial render.
This is commonly used for API requests.
Fetching Data from an API
Example:
import { useEffect } from "react";
function Users() {
useEffect(() => {
fetch("/api/users")
.then(res => res.json())
.then(data =>
console.log(data)
);
}, []);
return <h1>Users</h1>;
}
This is one of the most common useEffect use cases.
Updating the Page Title
Example:
useEffect(() => {
document.title =
"React Blog";
}, []);
When the component loads, the browser tab title changes.
Dependency Array Explained
The second argument is called the dependency array.
useEffect(() => {
// Logic
}, []);
React uses this array to determine when the effect should run.
No Dependency Array
Example:
useEffect(() => {
console.log("Runs");
});
Behavior:
Runs after
every render.
This is rarely desired.
Empty Dependency Array
Example:
useEffect(() => {
console.log("Runs Once");
}, []);
Behavior:
Runs only once.
Specific Dependencies
Example:
useEffect(() => {
console.log("Count Changed");
}, [count]);
Behavior:
Runs whenever
count changes.
This is very common in React applications.
Example with State
import {
useState,
useEffect
} from "react";
function Counter() {
const [count, setCount] =
useState(0);
useEffect(() => {
console.log(
"Count Updated"
);
}, [count]);
return (
<button
onClick={() =>
setCount(count + 1)
}
>
{count}
</button>
);
}
The effect runs every time count changes.
Cleanup Function
Some effects require cleanup.
Example:
useEffect(() => {
const timer =
setInterval(() => {
console.log("Running");
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
The returned function runs when:
- component unmounts
- effect re-runs
This prevents memory leaks.
Event Listener Example
useEffect(() => {
function handleResize() {
console.log(
window.innerWidth
);
}
window.addEventListener(
"resize",
handleResize
);
return () => {
window.removeEventListener(
"resize",
handleResize
);
};
}, []);
Cleanup ensures proper resource management.
Behind the Scenes
React follows this process:
Component Render
↓
DOM Updated
↓
useEffect Runs
Unlike rendering logic, effects execute after the UI is updated.
This helps keep rendering predictable.
Real Project Usage
Blog Application
useEffect can:
- fetch blog posts
- load categories
- update page metadata
- save reading preferences
Example:
useEffect(() => {
fetchPosts();
}, []);
E-commerce Website
useEffect can:
- load products
- update cart totals
- sync user preferences
Dashboard Application
useEffect can:
- fetch analytics
- load notifications
- connect to APIs
Common Real-World Use Cases
The useEffect Hook is commonly used for:
- API requests
- localStorage access
- authentication checks
- event listeners
- timers
- analytics tracking
- browser title updates
- WebSocket connections
Common Beginner Mistakes
Missing Dependency Array
Incorrect:
useEffect(() => {
fetchData();
});
This runs after every render.
Incorrect Dependencies
Incorrect:
useEffect(() => {
fetchData();
}, []);
when the effect depends on changing values.
Always include required dependencies.
Forgetting Cleanup
Incorrect:
useEffect(() => {
setInterval(() => {
console.log("Running");
}, 1000);
}, []);
This can create memory leaks.
Using useEffect for Everything
Not all logic belongs in useEffect.
Many beginners overuse it.
Use it only for side effects.
React useEffect Interview Questions
- What is useEffect in React?
- What are side effects?
- What is the purpose of the dependency array?
- What happens when the dependency array is empty?
- What happens when no dependency array is provided?
- Why is cleanup important?
- When should you use useEffect?
Watch Full React useEffect Tutorial
If you prefer video learning, watch the complete tutorial below where we build API integrations, timers, event listeners, and real-world examples using useEffect.
Watch the Full React useEffect Tutorial
This tutorial demonstrates practical useEffect patterns used in production applications.
React vs Next.js
The useEffect Hook behaves the same in React and Next.js Client Components.
However, useEffect only runs in the browser and does not execute during server-side rendering.
Understanding this distinction becomes important when learning Next.js.
Production Tip
Professional React developers usually:
- keep effects focused on one task
- clean up subscriptions properly
- avoid unnecessary effects
- use dependency arrays carefully
- move reusable effect logic into custom Hooks
Well-structured effects improve performance and maintainability.
Why useEffect Matters
The useEffect Hook allows React components to interact with APIs, browsers, and external systems while keeping rendering logic clean and predictable.
Without useEffect, building modern React applications would be significantly more difficult.
Conclusion
The useEffect Hook is React's primary solution for handling side effects inside functional components.
Whether you're fetching data, updating the browser title, listening for events, or managing timers, useEffect provides a clean and reliable way to perform these tasks.
Mastering useEffect is essential for building real-world React applications and understanding advanced React development patterns.