REACT & NEXT.JS / 2. USESTATE & USEEFFECT
useState & useEffect
State and side effects — the two most important hooks
EXPLANATION
Hooks let function components have state and lifecycle. Rules:
• Only call hooks at the top level (not inside loops, conditions, or nested functions)
• Only call hooks from React function components or custom hooks
useState: adds local state to a component.
const [value, setValue] = useState(initialValue)
• value → current state
• setValue → function to update state (triggers re-render)
• State updates are asynchronous — don't rely on state immediately after setting it
useEffect: runs side effects after render.
useEffect(() => { /* effect */ }, [dependencies])
• Empty array [] → run once on mount
• [dep1, dep2] → run when dep1 or dep2 changes
• No array → run after every render (almost never what you want)
• Return a cleanup function to prevent memory leaks
Common mistakes:
• Infinite loop: putting an object/array in deps without useMemo
• Missing dependency: eslint-plugin-react-hooks will warn you
• Not cleaning up: event listeners, subscriptions, timersDIAGRAM
Component lifecycle with hooks:
Mount → useEffect(fn, []) ← runs once
↓
Render → JSX returned
↓
User interacts → setState()
↓
Re-render → JSX returned again
↓
useEffect(fn, [dep]) ← runs if dep changed
↓
Unmount → cleanup function runs
State update batching (React 18):
handleClick() {
setA(1) ← doesn't re-render yet
setB(2) ← doesn't re-render yet
setC(3) ← doesn't re-render yet
} ← ONE re-render with all updatesCODE