Last updated: Apr 29, 2026
Hooks
React 16.8 introduced Hooks — functions that let you use state, effects, and other React features inside function components. Before hooks, adding state or lifecycle logic meant converting to a class component, dealing with this binding, constructor boilerplate, and wrapper hell from HoCs and render props. Hooks eliminated all of that.
Built-in Hooks
State
useState— local state in a function componentuseReducer— complex state managed through a reducer function
Effects
useEffect— run side effects (data fetching, subscriptions, DOM mutations) after renderuseLayoutEffect— same asuseEffectbut fires synchronously after DOM mutations, before the browser paintsuseInsertionEffect— inject styles before layout reads; meant for CSS-in-JS libraries
Context
useContext— read a context value without a Consumer wrapper
Refs
useRef— hold a mutable value that persists across renders (commonly a DOM node)useImperativeHandle— customize the ref value a parent sees when usingref
Performance
useMemo— memoize an expensive computation so it only recalculates when dependencies changeuseCallback— memoize a function reference to avoid unnecessary re-renders of childrenuseTransition— mark a state update as non-urgent so the UI stays responsive (React 18)useDeferredValue— defer re-rendering a value until higher-priority updates finish (React 18)
Identity
useId— generate a stable unique ID for accessibility attributes likehtmlFor/idpairs (React 18)
Debug
useDebugValue— display a label for custom hooks in React DevTools
External Stores
useSyncExternalStore— subscribe to an external store with built-in tearing protection (React 18)
React 19
use— read a Promise or Context; unlike other hooks, it can be called conditionallyuseActionState— track the return value and pending state of an async form actionuseFormStatus— read the submission status of a parent<form>from a child componentuseOptimistic— show an optimistic value instantly while an async operation settles
Custom Hooks
A custom hook is a function whose name starts with use and that composes built-in hooks. It lets you extract and share stateful logic between components without adding wrapper layers.
function useKeyPress(targetKey: string): boolean {
const [pressed, setPressed] = useState(false);
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === targetKey) setPressed(true);
};
const up = (e: KeyboardEvent) => {
if (e.key === targetKey) setPressed(false);
};
window.addEventListener("keydown", down);
window.addEventListener("keyup", up);
return () => {
window.removeEventListener("keydown", down);
window.removeEventListener("keyup", up);
};
}, [targetKey]);
return pressed;
}
Any component can call useKeyPress("Enter") to react to that key — no HoC or render prop needed.
Rules of Hooks
- Call hooks at the top level only. No hooks inside loops, conditions, or nested functions. React relies on call order to match state to the right hook.
- Call hooks from React functions only. Either a function component or another custom hook — never a plain JavaScript function.
The eslint-plugin-react-hooks plugin enforces both rules at lint time.