Skip to main content

Hooks

Hooks are functions such as useState and useEffect; their names start with use. They give function components access to React features: state, effects, context, refs. There are two rules: call hooks only at the top level (not in conditions, loops, nested functions or after an early return) and only from React functions (components and custom hooks). The reason is that React matches a hook call with its stored state by the order of calls.

Applies to: React 19.3.

Details​

Built-in Hooks​

HookPurposePage
useStateState of a componentState
useReducerState with update logic in a reducerState
useContextRead a context valueContext
useRefA mutable value that does not cause re-renders; access to DOM nodesRefs
useImperativeHandleCustomize what a ref to the component exposesRefs
useEffectSynchronize with an external system after renderSide Effects
useLayoutEffectThe same, but before the browser paintsSide Effects
useInsertionEffectInsert styles before layout effects; for CSS-in-JS libraries—
useEffectEventA function that reads the latest props and state inside an effectSide Effects
useMemoCache a computed value between rendersOptimization
useCallbackCache a function between rendersOptimization
useTransitionMark a state update as non-urgentConcurrent Rendering
useDeferredValueA value that lags behind during urgent updatesConcurrent Rendering
useIdA unique ID that is the same on the server and the client—
useSyncExternalStoreSubscribe to a store outside of React—
useActionStateState and pending flag of an ActionForms
useOptimisticShow the expected result while an Action is pendingForms
useFormStatusStatus of the parent <form> (from react-dom)Forms
useRead a promise or a context. An API, not a hook: allowed in ifConcurrent Rendering

Rules of Hooks​

  1. Only call hooks at the top level. React keeps the hooks of a component in a list and finds each one by its position. If a call is skipped, every hook after it gets the wrong state.
  2. Only call hooks from React functions: function components and custom hooks. Not from regular functions, class components or event handlers.
  • use is an API, not a hook, so the first rule does not apply to it: it can be called in a condition or a loop, but still only inside a component or a hook.
  • The rules are checked by eslint-plugin-react-hooks.

Custom Hooks​

  • A custom hook is a function named use… that calls other hooks.
  • It shares logic, not state: every component that calls the hook gets its own independent state.
  • It replaces HOCs and render props and can be tested separately from the UI.
  • A function that calls no hooks should not be named use….

Example​

A condition goes inside the hook, not around it:

import { useEffect } from 'react';

function Chat({ roomId, isOnline }) {
// Wrong: the hook is skipped on some renders
if (isOnline) {
useEffect(() => connect(roomId), [roomId]);
}

// Right: the hook is always called, the condition is inside
useEffect(() => {
if (!isOnline) {
return;
}

return connect(roomId);
}, [roomId, isOnline]);

return <p>Room: {roomId}</p>;
}

A custom hook:

import { useCallback, useState } from 'react';

export default function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);

const toggle = useCallback(() => {
setValue((prevValue) => !prevValue);
}, []);

return [value, toggle];
}

Follow-up Questions​

  • What problems did hooks solve? Stateful logic is reused without HOCs and render props (no "wrapper hell"), a component's logic is split by concern instead of by lifecycle method, and there is no this.
  • Why can't hooks be called conditionally? React identifies a hook by its call order, not by a name.
  • Do two components that use the same custom hook share state? No. To share state, lift it up or use context or a store.
  • Can hooks be used in class components? No. A class can be wrapped in a function component that calls the hook and passes the result as props.

Common Mistakes​

  • An early return above a hook call.
  • Calling a hook inside a callback, an event handler or useMemo.
  • Giving "not in conditions" and "not in loops" as the two rules: that is one rule; the second one is about where hooks can be called from.

See Also​