useEffect
is a React Hook that lets you perform side effects in functional components. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount combined in React class components.
useEffect(() => {
// Side effect code here
console.log('Effect runs');
// Optional cleanup function
return () => {
console.log('Cleanup runs');
};
}, [dependencies]); // Optional dependency array
// Common patterns:
useEffect(() => {}); // Runs on every render
useEffect(() => {}, []); // Runs only once (mount)
useEffect(() => {}, [count]); // Runs when count changes
Current page title: Loading...
Check the browser tab title - it updates automatically when count changes!
This example shows useEffect with dependency array: useEffect(() => {}, [count])
Current Title: useEffect Demo
This effect depends on both 'count' and 'pageTitle' variables
This example shows useEffect with multiple dependencies: useEffect(() => {}, [count, pageTitle])
🔄 Loading data automatically...
This data was fetched automatically when the component mounted using: useEffect(() => {}, [])
This example shows async data fetching with loading and error states
⏱️ 0s
Timer Status: 🔴 Stopped
✅ This example shows useEffect with cleanup functions to prevent memory leaks
Window Size: Loading...
Try resizing your browser window to see this update in real-time!
✅ This example shows useEffect for event listeners with proper cleanup
Saved Text: (empty)
This text is automatically saved to localStorage and will persist across page refreshes!
✅ This example shows useEffect for data persistence with localStorage
Always include all variables from component scope that are used inside useEffect in the dependency array.
❌ Wrong:
useEffect(() => {
console.log(count);
}, []); // Missing 'count' in dependencies
✅ Correct:
useEffect(() => {
console.log(count);
}, [count]); // Include 'count' in dependencies
Always clean up subscriptions, timers, and event listeners to prevent memory leaks.
❌ Wrong:
useEffect(() => {
const interval = setInterval(() => {
console.log('tick');
}, 1000);
// No cleanup!
}, []);
✅ Correct:
useEffect(() => {
const interval = setInterval(() => {
console.log('tick');
}, 1000);
return () => clearInterval(interval);
}, []);
Be careful with object/array dependencies and missing dependency arrays.
❌ Wrong:
useEffect(() => {
setUser({ name: 'John' });
}); // No dependency array = runs on every render
✅ Correct:
useEffect(() => {
setUser({ name: 'John' });
}, []); // Empty array = runs once on mount