Introduction
Developers often need to perform operations such as:
- Fetching API data
- Updating the document title
- Setting timers
- Handling subscriptions
- Working with local storage
These operations are called Side Effects in React.
Before React Hooks were introduced, side effects were mainly handled using lifecycle methods in class components such as:
- componentDidMount
- componentDidUpdate
- componentWillUnmount
However, lifecycle methods made components more complex and difficult to manage.
The useEffect Hook allows functional components to perform side effects easily and efficiently.
What is useEffect Hook?
The useEffect Hook is a React Hook used to handle side effects inside functional components.
It allows React components to:
- Run code after rendering
- Fetch data
- Update the DOM
- Manage timers
- Clean up resources
What are Side Effects?
Side effects are operations that affect something outside the component.
Examples:
- API calls
- Timers
- Event listeners
- Updating browser title
- Local storage access
Why useEffect is Used?
React components mainly focus on rendering UI.
However, applications also need:
- External data fetching
- Background operations
- Dynamic updates
useEffect helps manage these operations cleanly.
Syntax of the useEffect Hook
Basic syntax:
useEffect(() => {
// Side effect code
}, []);
Understanding the Syntax
First Argument
A callback function containing side effect logic.
Second Argument
Dependency array controlling when the effect runs.
Basic Example of useEffect
import { useEffect } from "react";
function App() {
useEffect(() => {
console.log("Component Rendered");
}, []);
return <h1>Hello React</h1>;
}
export default App;
Output
The effect runs after the component renders.
useEffect Without Dependency Array
useEffect(() => {
console.log("Runs Every Render");
});
Behavior
The effect runs:
- After every render
- After every state update
useEffect with Empty Dependency Array
useEffect(() => {
console.log("Runs Once");
}, []);
Behavior
Runs only once when the component mounts.
Equivalent to:
componentDidMount
useEffect with Dependencies
import { useState, useEffect }
from "react";
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Count Updated");
}, [count]);
return (
<button onClick={() => setCount(count + 1) } >
{count}
</button>
);
}
}
Behavior
Effect runs whenever
- count changes
Real-Life Example of useEffect
Suppose you are building an e-commerce website.
You may need:
- Product data fetching
- Cart synchronization
- Authentication checks
- Search filtering
useEffect handles these operations efficiently.
Fetching API Data with useEffect
One of the most common uses of useEffect is API fetching.
Example
import { useState, useEffect }
from "react";
function App() {
const [users, setUsers] =
useState([]);
useEffect(() => {
fetch(
"https://jsonplaceholder.typicode.com/users"
)
.then((response) =>
response.json()
)
.then((data) =>
setUsers(data)
);
}, []);
return (
<div>
{
users.map((user) => (
<h2 key={user.id}>
{user.name}
</h2>
))
}
</div>
);
}
Output
Cleanup Function in useEffect
Sometimes effects need cleanup.
Examples:
- Timers
- Event listeners
- Subscriptions
React provides cleanup functions.
Syntax of Cleanup Function
useEffect(() => {
return () => {
// Cleanup code
};
}, []);
Timer Example with Cleanup
import { useEffect } from "react";
function App() {
useEffect(() => {
const timer =
setInterval(() => {
console.log("Running");
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
return <h1>Timer Example</h1>;
}
Why is cleanup important?
Cleanup prevents:
- Memory leaks
- Unnecessary background tasks
- Performance issues
useEffect vs Lifecycle Methods
Before Hooks, lifecycle methods handled side effects.
useEffect combines:
- componentDidMount
- componentDidUpdate
- componentWillUnmount
Comparison Table
| Feature | useEffect Hook | Class Lifecycle Methods |
|---|---|---|
| Syntax | Simple | Complex |
| Functional Components | Supported | Not Supported |
| Side Effects | Supported | Supported |
| Cleanup | Easy | More Complex |
| Modern Usage | Recommended | Less Common |
Multiple useEffect Hooks
Components can use multiple effects.
Example
useEffect(() => {
console.log("Effect One");
}, []);
useEffect(() => {
console.log("Effect Two");
}, []);
Benefits of Multiple Effects
- Cleaner code
- Better separation of logic
- Easier maintenance
Dependency Array in useEffect
Dependency array controls effect execution.
Types of Dependency Arrays
| Dependency Array | Behavior |
|---|---|
| No Array | Runs every render |
| Empty Array [] | Runs once |
| [value] | Runs when value changes |
Common useEffect Use Cases
useEffect is commonly used for:
- API calls
- Timers
- Authentication checks
- DOM updates
- Event listeners
- Data synchronization
Advantages of useEffect Hook
| Feature | Benefit |
|---|---|
| Side Effect Handling | Better application control |
| Functional Components | Modern React development |
| Cleaner Code | Easier readability |
| Dependency Control | Optimized rendering |
| Cleanup Support | Prevents memory leaks |
Common Mistakes in useEffect
1. Missing Dependency Array
Wrong:
useEffect(() => {
console.log("Hello");
});
Runs after every render.
2. Infinite Loop Problem
Wrong:
useEffect(() => {
setCount(count + 1);
}, [count]);
This creates infinite re-renders.
3. Forgetting Cleanup
Timers and listeners should always be cleaned.
4. Using Too Many Effects
Avoid unnecessary effects.
5. Incorrect Dependencies
Missing dependencies may cause bugs.
Best Practices for useEffect
- Use dependency arrays properly
- Keep effects focused
- Always clean up timers/listeners
- Avoid unnecessary re-renders
- Separate unrelated effects
- Avoid infinite loops
Real-World Applications of useEffect
useEffect is heavily used in:
- Social media apps
- E-commerce websites
- Banking systems
- Dashboards
- Chat applications
Examples:
- Fetching products
- User authentication
- Notifications
- Timers
- Real-time updates
useEffect vs Normal JavaScript Functions
| Feature | useEffect | JavaScript Function |
|---|---|---|
| React Lifecycle Access | Yes | No |
| Side Effect Handling | Yes | Limited |
| Dependency Tracking | Yes | No |
| Automatic Re-run | Yes | No |
useEffect Hook – Interview Questions
Q 1: What is the purpose of useEffect?
Q 2: When does useEffect run?
Q 3: What is the dependency array in useEffect?
Q 4: How do you run useEffect only once?
Q 5: Can useEffect replace lifecycle methods?
useEffect Hook– Objective Questions (MCQs)
Q1. What is the primary purpose of the useEffect hook in React?
Q2. When does the effect run if no dependency array is provided?
Q3. How do you run an effect only once after the first render?
Q4. Which of the following is a valid cleanup in useEffect?
Q5. Which of these is a side effect suitable for useEffect?
Conclusion
The useEffect Hook is one of the most important Hooks in React because it allows functional components to handle side effects efficiently. It simplifies lifecycle management and makes React applications cleaner and easier to maintain.
useEffect is commonly used for:
- API fetching
- Timers
- Event listeners
- Authentication
- DOM updates