Every React Hook, Catalogued: From useState to Custom Logic Reuse
Hooks are the standard React component model now; class components are legacy. Knowing when to use `useLayoutEffect` over `useEffect`, or how `useTransition` keeps typing responsive during expensive renders, directly affects perceived performance and correctness in production React apps.
React Hooks turn function components into full-featured units that manage state, side effects, and context without classes. Two hard rules govern their use: call them only at the top level of a React function, and never inside loops, conditionals, or plain JavaScript functions. Breaking those rules scrambles the call-order state tracking React depends on.
The guide groups the 13 built-in Hooks into six categories. State Hooks (`useState`, `useReducer`) handle simple and complex state; Context (`useContext`) replaces prop drilling; Ref Hooks (`useRef`, `useImperativeHandle`) hold non-rendering data and limit parent access to child internals; Effect Hooks (`useEffect`, `useLayoutEffect`) synchronize with external systems, with `useLayoutEffect` running synchronously before the browser paints to avoid flicker. Performance Hooks (`useMemo`, `useCallback`) cache values and function references to skip work, though the advice is to reach for them only when a measured problem exists.
React 18 added `useTransition` and `useDeferredValue` for marking non-urgent updates that can be interrupted by urgent ones (like keystrokes), and `useId` for generating stable unique IDs across server and client. The final section demonstrates three custom Hooks — online status, localStorage sync, and debounce — and distills the practice into a rule: when logic repeats across components, extract a Hook whose name begins with `use`.
The two Hook rules are not stylistic; they exist because React relies on stable call-order indexing to associate state with the correct `useState` or `useEffect` call across renders. Conditional or looped calls break that index.
The guide explicitly warns that `useEffect` is an escape hatch for external-system interaction — a reminder that overusing effects for derived state or synchronization that React can handle declaratively is a common anti-pattern.
`useMemo` and `useCallback` are presented with a caution against premature use, aligning with the React team's own stance that memoization should follow measurement, not habit.
React 18's `useTransition` and `useDeferredValue` represent a meaningful shift in mental model: developers now explicitly categorize updates by urgency, letting the runtime interleave high-priority and low-priority work instead of processing them sequentially.
The custom Hook examples — online status, localStorage, debounce — are small but illustrate the core value proposition: Hooks make stateful behavior a composable unit, not something locked inside a component or a higher-order wrapper.