What is a Hook?
A hook is a special function, always starting with "use", that lets a function component tap into React features — state, side effects, refs, context, and more — without needing to write a class.
Why Hooks Exist
Before hooks (introduced in React 16.8), stateful logic could only live in class components, using lifecycle methods like componentDidMount. Hooks let that same logic live in plain functions, making it far easier to reuse (via custom hooks) and to keep related logic grouped together instead of split across lifecycle methods.
Every Hook Covered in This Section
| Hook | Purpose |
|---|---|
| useState | Give a component memory that persists across renders |
| useEffect | Synchronize with an external system after rendering |
| useLayoutEffect | Like useEffect, but fires synchronously before the browser paints |
| useContext | Read a value from a Context Provider, avoiding prop drilling |
| useReducer | Manage complex, related state transitions with a reducer function |
| useRef | Access a DOM node or persist a mutable value without re-rendering |
| useImperativeHandle | Customize the ref instance value exposed by a component |
| useMemo | Cache the result of an expensive calculation between renders |
| useCallback | Cache a function reference between renders |
| useTransition | Mark a state update as low-priority so the UI stays responsive |
| useDeferredValue | Defer re-rendering a non-urgent part of the UI |
| useId | Generate a unique, SSR-safe id for accessibility attributes |
| useSyncExternalStore | Safely subscribe to a store outside of React |
| useDebugValue | Label a custom hook’s value in React DevTools |
| use | Read a Promise or Context value, callable conditionally |
| useOptimistic | Show an expected result immediately before an async action finishes |
| useActionState | Track a form Action’s pending state and result |
| useFormStatus | Read the pending status of the nearest parent form |
The Rules of Hooks
Hooks rely on being called in the exact same order on every render, so React can correctly match each hook call to its internal state between renders. This leads to two strict rules.
The Two Rules
- Only call hooks at the top level — never inside loops, conditions, or nested functions.
- Only call hooks from React function components or from other custom hooks — never from plain JavaScript functions.
Breaking the Rules (Don’t Do This)
function Profile({ showBio }) {
// Wrong: a hook call inside a condition changes the order between renders
if (showBio) {
const [bio, setBio] = useState("");
}
// Correct: call the hook unconditionally, then branch on the value
const [bio, setBio] = useState("");
if (showBio) {
// use bio here
}
}A Linter Catches Most Violations Automatically
The eslint-plugin-react-hooks package (included by default in most React project templates) flags Rules of Hooks violations and missing effect dependencies as you type, so you rarely need to memorize every edge case manually.
Best Practice
Use this section as a reference. You don’t need to memorize every hook up front — come back to a specific hook’s lesson whenever you hit a problem it solves (measuring layout, deferring a slow render, subscribing to an external store, and so on).