liveBook · Manning

Custom hook

As explained in React Quickly, Second Edition

A custom hook is a developer-defined function that composes React Hooks to provide reusable component logic.

Suppose a countdown needs a Boolean value that flips whenever its button is clicked. Instead of repeating the state update in the component, put it in a custom hook: a function that calls a React hook and exposes useful logic. section 10.3.2 section 10.3.1

function useToggle(default = false) {
 const [value, setter] = useState(Boolean(default));
 const toggle = () => setter(v => !v);
 return [value, toggle];
}

useToggle keeps Boolean state with useState and returns the value alongside a function that flips it. section 10.3.2

Use the toggle in a countdown

Inside Countdown, write `const [isRunning, toggleRunning] = useToggle();` and give the button `onClick={toggleRunning}`. Compared with an inline update such as `setRunning(v => !v)`, the component no longer needs to spell out how toggling works. Like useState, this hook returns a value-and-function pair; unlike useState’s setter, its function only inverts the Boolean value. section 10.3.2

A function becomes a custom hook by calling a built-in hook, or another custom hook that ultimately calls one. No registration is needed. The `use` prefix is a naming convention, not what makes the function a hook; use it for hooks and avoid it for other functions. section 10.3.1 section 10.5

Extract logic when it is needed in multiple places or when keeping it in a component makes the UI harder to read:

  • A `useForm(initialValues)` hook can hold form data and return an `onChange` handler for named inputs. section 10.3.2
  • A small `useName()` hook can return `useContext(NameContext)`, so components share one way to access that context. section 10.3
  • A `useCounter()` hook can move counter state and increment/decrement handlers out of a styled counter component. section 10.3.2

The rules of hooks still apply through every layer: call a custom hook from a functional component or another custom hook, and keep hook calls in the same order on every render. Do not put them in conditions, loops, callbacks, or after an optional early return. A helper function cannot bypass these rules. section 7.5 section 5.2.1

Hooks package functionality rather than UI elements. They can be shared across components and applications, written for a particular component’s readability, or obtained from hook libraries. For larger state flows, a custom hook can also wrap a reducer; a timer that gains a reset action is one practical reason to make that refactor. section 10.3.2 section 10.3.3 section 12.0

How React Quickly, Second Edition covers it

How deep it goes
Defines what qualifies as a custom hook and works through state, context, form, and reducer extractions.
Examples
Shows a countdown toggle, form handler, context accessor, counter, and reducer-backed loader; also proposes a timer reset refactor.
What it assumes
Assumes familiarity with functional components and built-in hooks such as useState; defines what makes a function a custom hook.
What you can do after
Build it from scratch to share hook-based logic or simplify a component while preserving the rules of hooks.
How it connects
Connects React Hooks and functional components with state, React Context, reducers, and the rules of hooks.

Also explained in

Compare how 4 books explain custom hook →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React Quickly, Second Edition. The section links point to the parts of the book it draws on.