💡 Key Takeaways
- React Hooks let you manage state, side effects, refs, context, and memoization in functional components.
useState & useReducer handle state; useEffect & useLayoutEffect handle side effects.
useMemo & useCallback optimize performance.
useContext shares data without prop drilling; useImperativeHandle exposes controlled child methods.
🔹 useState – State in Functional Components
- Add local state in functional components
- Returns
[state, setState]
- Supports primitives, objects, arrays
- Use functional updates when new state depends on previous
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>{count}</button>
🔹 useEffect – Side Effects
- Run after render cycles
- Supports dependencies for selective updates
- Return cleanup function for unmounts
- Replaces lifecycle methods
useEffect(() => {
console.log("Component mounted or updated");
return () => console.log("Cleanup on unmount");
}, []);
🔹 useRef – Mutable Ref / DOM Access
- Store mutable value across renders
- Access DOM elements or instance values
- Does not trigger re-renders
const inputRef = useRef(null);
useEffect(() => inputRef.current.focus(), []);
<input ref={inputRef} />
🔹 useContext – Access Context Values
- Consume context without prop drilling
- Works for themes, auth, or global state
- Reactively updates when provider value changes
const theme = useContext(ThemeContext);
<div style={{ color: theme.color }}>Themed!</div>
🔹 useReducer – Alternative to useState
- Manage complex state with a reducer function
- Returns
[state, dispatch]
- Predictable state transitions for nested or multiple updates
const [state, dispatch] = useReducer(reducer, { count: 0 });
<button onClick={() => dispatch({ type: 'increment' })}>{state.count}</button>
🔹 useMemo – Memoize Expensive Calculations
- Memoize values based on dependencies
- Avoids recalculating heavy operations on each render
const result = useMemo(() => slowFunction(num), [num]);
<div>{result}</div>
🔹 useCallback – Memoize Functions
- Memoize function references to avoid re-renders
- Works with dependencies for dynamic updates
const handleClick = useCallback(() => console.log("Clicked"), []);
🔹 useLayoutEffect – Synchronous Effect Before Paint
- Runs before browser paints
- Ideal for DOM measurements or layout adjustments
useLayoutEffect(() => {
}, []);
🔹 useImperativeHandle – Customize Child Ref
- Expose specific child methods to parent via
ref
- Use with
forwardRef to control accessible methods
useImperativeHandle(ref, () => ({ focus: () => inputRef.current.focus() }));