Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
useEffect lets you perform side effects in function components. Side effects are operations that affect things outside the component - like data fetching, subscriptions, or manually changing the DOM.
Code that runs after render to start the effect
Optional function to clean up before re-running or unmounting
Array of values that trigger effect re-run when changed
First, import useEffect from React at the top of your component file.
Pro Tip
You can import multiple hooks at once: { useState, useEffect, useContext }.
Use useEffect with a function that contains your side effect code.
Key Point
This effect runs after every render. Use dependency arrays to control when it runs!
Control when your effect runs by adding a dependency array as the second argument.
Important
Empty array [] = runs once on mount. Include dependencies to re-run when they change!
Return a cleanup function to prevent memory leaks and handle cleanup.
Key Point
Cleanup runs before the next effect and when component unmounts. Perfect for subscriptions!
Fetch data when component mounts
function UserProfile() {
const [user, setUser] = React.useState(null);
const [loading, setLoading] = React.useState(true);
// Effect runs after first render
React.useEffect(() => {
setLoading(true);
// Simulate API call
setTimeout(() => {
const mockUser = {
name: 'John Doe',
email: 'john@example.com',
role: 'Developer'
};
setUser(mockUser);
setLoading(false);
}, 1500);
}, []); // Empty array = run once on mount
return (
<div className="container">
<h1>👤 User Profile</h1>
{loading ? (
<div className="loading">
<div className="spinner"></div>
<p>Loading user data...</p>
</div>
) : (
<div className="profile">
<div className="avatar">
{user.name.charAt(0)}
</div>
<div className="info">
<h2>{user.name}</h2>
<p className="email">{user.email}</p>
<span className="role">{user.role}</span>
</div>
</div>
)}
<div className="info-box">
💡 useEffect with empty [] runs once on mount
</div>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<UserProfile />);Loading preview...
⚠️ Usually not what you want - can cause performance issues!
✅ Perfect for data fetching, subscriptions that don't change
✅ Re-fetch data when props/state change
Cleanup stops the timer when unmounting
function LiveClock() {
const [time, setTime] = React.useState(new Date());
const [isRunning, setIsRunning] = React.useState(true);
React.useEffect(() => {
if (!isRunning) return;
// Setup: Start interval
const interval = setInterval(() => {
setTime(new Date());
}, 1000);
// Cleanup: Stop interval
return () => {
clearInterval(interval);
};
}, [isRunning]);
const hours = time.getHours().toString().padStart(2, '0');
const minutes = time.getMinutes().toString().padStart(2, '0');
const seconds = time.getSeconds().toString().padStart(2, '0');
return (
<div className="container">
<h1>⏰ Live Clock</h1>
<div className="clock">
<div className="time">{hours}:{minutes}:{seconds}</div>
<div className="date">{time.toLocaleDateString()}</div>
</div>
<button
onClick={() => setIsRunning(!isRunning)}
className="btn-toggle"
>
{isRunning ? 'Pause' : 'Start'} Clock
</button>
<div className="info-box">
<h3>✨ Cleanup Function:</h3>
<p>Prevents memory leaks by clearing the interval when component unmounts or effect re-runs</p>
</div>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<LiveClock />);Loading preview...
Effects run after render, not during. This keeps rendering fast!
Return a cleanup function to prevent memory leaks from timers, subscriptions, etc.
Always include values from component scope that the effect uses in the dependency array.
Use for fetching data, subscriptions, timers, and DOM manipulation.