1. What are Side Effects in React?
A pure React component should only calculate JSX from props and state without performing outside interactions during render. Any operation that interacts with the outside world is a side effect, such as:
- Fetching data from a REST API or backend server.
- Setting up timers (
setInterval,setTimeout). - Directly manipulating the browser DOM (e.g., updating
document.title). - Subscribing to WebSocket events or global browser listeners.
2. The useEffect Hook Anatomy
import { useEffect } from 'react';
useEffect(() => {
// 1. Effect callback code runs after render
return () => {
// 2. Optional cleanup function runs before unmount or next effect execution
};
}, [/* 3. Dependency Array */]);
3. The Three Dependency Modes
Mode A: No Dependency Array
useEffect(() => {
console.log("Runs after EVERY single render!");
});
Mode B: Empty Dependency Array ([])
useEffect(() => {
console.log("Runs only ONCE when component mounts (loads)!");
}, []);
Mode C: With Specific Dependencies ([dep1, dep2])
useEffect(() => {
console.log("Runs on mount AND whenever examId changes!");
fetchExamDetails(examId);
}, [examId]);
4. Cleanup Functions: Timers & Subscriptions
If an effect sets up a timer or listener, it must clean up after itself when the component unmounts to prevent memory leaks:
import { useState, useEffect } from 'react';
function ExamCountdownTimer({ totalSeconds }) {
const [secondsLeft, setSecondsLeft] = useState(totalSeconds);
useEffect(() => {
const timerInterval = setInterval(() => {
setSecondsLeft(prev => {
if (prev <= 1) {
clearInterval(timerInterval);
return 0;
}
return prev - 1;
});
}, 1000);
// CLEANUP FUNCTION: Clears interval when user leaves page or component unmounts
return () => clearInterval(timerInterval);
}, []);
return Remaining: {secondsLeft}s;
}