Basic Syntax
- Run side effects (event listeners, API calls, subscriptions, etc.) after render
useEffect
runs after the DOM is painted (non-blocking, async)
- Does not run during render — for pre-paint logic, use
useLayoutEffect
useEffect(() => {
// Side-effect logic here
return () => {
// Cleanup logic here
};
}, [dependencies]);
Dependency Array
[]
: run once after mount, cleanup on unmount
- No array: run after every render (rarely used)
[a, b]
: run after mount, and again if a
or b
changes
Cleanup Function
- Runs before the next effect (on dependency change)
- Also runs on unmount
- Use for: unsubscribing, removing listeners, canceling async tasks
useEffect(() => {
const timer = setInterval(() => console.log("tick"), 1000);
return () => clearInterval(timer);
}, []);
Example: Resize Listener
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth < 768);
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);