💡 Key Takeaways
useState & useReducer manage component state (local vs complex).
useEffect & useLayoutEffect handle side effects and DOM updates.
useContext shares global state without prop drilling.
useMemo & useCallback optimize performance.
useRef & useImperativeHandle handle DOM refs and custom child APIs.
🔹 useState – Local State
- Add state in functional components
[state, setState] tuple
- Works for primitives, arrays, objects
- Use functional updates for dependent state
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>{count}</button>
🔹 useReducer – Complex State
- Manage multiple or nested state transitions
- Returns
[state, dispatch]
- Reducer function keeps updates predictable
const [state, dispatch] = useReducer(reducer, { count: 0 });
<button onClick={() => dispatch({ type: 'increment' })}>{state.count}</button>
🔹 useEffect – Side Effects
- Run after render cycles
- Supports dependency arrays
- Return cleanup function for unmounts
useEffect(() => {
console.log("Component mounted or updated");
return () => console.log("Cleanup");
}, []);
🔹 useLayoutEffect – Sync Effect Before Paint
- Runs before browser paints
- Useful for DOM measurements or layout adjustments
useLayoutEffect(() => {
}, []);
🔹 useContext – Access Global State
- Consume context without prop drilling
- Reactive updates on provider value change
const theme = useContext(ThemeContext);
<div style={{ color: theme.color }}>Themed!</div>
🔹 useMemo – Memoize Values
- Avoid recalculating expensive computations
- Recompute only when dependencies change
const result = useMemo(() => slowFunction(num), [num]);
<div>{result}</div>
🔹 useCallback – Memoize Functions
- Memoize functions to prevent unnecessary re-renders
- Update function reference based on dependencies
const handleClick = useCallback(() => console.log("Clicked"), []);
🔹 useRef – Mutable Ref / DOM Access
- Persist mutable values across renders
- Access DOM nodes or store instance values
- Updates do not trigger re-renders
const inputRef = useRef(null);
useEffect(() => inputRef.current.focus(), []);
<input ref={inputRef} />
🔹 useImperativeHandle – Custom Child API
- Expose specific methods from child to parent via
ref
- Use with
forwardRef
useImperativeHandle(ref, () => ({ focus: () => inputRef.current.focus() }));