The useEffect
hook is crucial in React for handling side effects, such as data fetching, subscriptions, timers, or manually changing the DOM. This guide covers useEffect
with practical examples.
🛠️ Understanding useEffect
The useEffect
hook allows you to perform side effects in functional components. It runs after the render cycle and can be controlled using dependencies.
Basic Syntax:
useEffect(() => {
// Side effect logic
return () => {
// Cleanup (if needed)
};
}, [dependencies]);
- Runs on Mount (Empty dependency array
[]
) - Runs on Update (List dependencies
[state, props]
) - Runs on Unmount (Cleanup function inside
return
)
Visualizing useEffect
1️⃣ Fetching Data
Fetching User Profile (Social Media App)
import { useEffect, useState } from "react";
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`https://api.example.com/users/${userId}`)
.then((res) => res.json())
.then((result) => setUser(result));
}, [userId]);
return user ? <h2>{user.name}</h2> : <p>Loading...</p>;
}
Fetching Product List (E-Commerce Site)
function ProductList() {
const [products, setProducts] = useState([]);
useEffect(() => {
fetch("https://api.example.com/products")
.then((res) => res.json())
.then((data) => setProducts(data));
}, []);
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
2️⃣ Subscriptions & Event Listeners
Live Chat Listener (Messaging App)
function ChatComponent({ chatId }) {
useEffect(() => {
const socket = new WebSocket(`wss://chat.example.com/${chatId}`);
socket.onmessage = (event) => console.log("New message: ", event.data);
return () => socket.close(); // Cleanup on unmount
}, [chatId]);
return <p>Chat Active</p>;
}
Listening for Window Resize (Responsive UI)
function WindowSize() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return <p>Window Width: {width}px</p>;
}
3️⃣ Managing Timers & Intervals
Auto-Logout Timer (Banking App)
function AutoLogout({ logout }) {
useEffect(() => {
const timer = setTimeout(() => {
logout();
}, 300000); // 5 minutes
return () => clearTimeout(timer); // Cleanup on user activity
}, []);
return <p>Auto logout enabled</p>;
}
Countdown Timer (Auction App)
function CountdownTimer({ initialTime }) {
const [timeLeft, setTimeLeft] = useState(initialTime);
useEffect(() => {
if (timeLeft <= 0) return;
const timer = setInterval(() => {
setTimeLeft((prev) => prev - 1);
}, 1000);
return () => clearInterval(timer);
}, [timeLeft]);
return <p>Time left: {timeLeft}s</p>;
}
4️⃣ Synchronizing with State Changes
Theme Toggle (E-Commerce Site)
function ThemeToggle({ theme }) {
useEffect(() => {
document.body.className = theme;
}, [theme]);
return <p>Current Theme: {theme}</p>;
}
Syncing Cart with Local Storage (Shopping Cart App)
function ShoppingCart({ cartItems }) {
useEffect(() => {
localStorage.setItem("cart", JSON.stringify(cartItems));
}, [cartItems]);
return <p>Cart Updated</p>;
}
5️⃣ Cleanup Effects
Music Player (Streaming App)
function MusicPlayer({ trackUrl }) {
useEffect(() => {
const audio = new Audio(trackUrl);
audio.play();
return () => {
audio.pause();
audio.src = "";
};
}, [trackUrl]);
return <p>Playing music...</p>;
}
Removing Event Listeners (Dashboard App)
function Dashboard() {
useEffect(() => {
const handleScroll = () => console.log("User is scrolling");
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return <p>Scroll to see effect in console</p>;
}
📈 Summary
Understanding useEffect
is essential for managing side effects, event listeners, API calls, and subscriptions in React. By structuring effects into data fetching, subscriptions, timers, synchronization, and cleanup, you can build real-world applications efficiently.