How to Create a Custom Hook in React

Learn the steps to extract repeated stateful logic into a reusable custom Hook, name it correctly, and call it from any component.

6 min read

A custom Hook in React is a JavaScript function whose name starts with use and that calls other Hooks inside it. It moves stateful logic out of a component, so several components can share the same behavior without copying the same lines of code.

Start with repeated stateful logic

The clearest signal for a custom Hook is the same state logic copied into more than one component. This Details component tracks whether its extra content is open.

App.jsxApp.jsx
import { useState } from "react";
 
function Details() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <div>
      <button onClick={() => setIsOpen(!isOpen)}>Show details</button>
      {isOpen && <p>Extra information goes here.</p>}
    </div>
  );
}

A Menu component would repeat the same useState call and the same toggle handler for its own open state. What gets copied is stateful logic, not markup.

Move the logic into a function

Create a function whose name starts with use, move the Hook calls into it, and return only what callers need.

App.jsxApp.jsx
import { useState } from "react";
 
function useToggle(initialValue) {
  const [value, setValue] = useState(initialValue);
  function toggle() {
    setValue((current) => !current);
  }
  return [value, toggle];
}

The name useToggle tells readers and the linter that this function is a Hook. It returns an array in the same shape as useState, so callers can destructure both items the same way.

Call your Hook from the component

With the Hook in its own file, import it and replace the copied logic with one call.

App.jsxApp.jsx
import { useToggle } from "./useToggle.js";
 
function Details() {
  const [isOpen, toggleOpen] = useToggle(false);
  return (
    <div>
      <button onClick={toggleOpen}>Show details</button>
      {isOpen && <p>Extra information goes here.</p>}
    </div>
  );
}

Passing false sets the initial open state. Clicking the button runs toggleOpen, which flips the value, and React re-renders the button and the extra content.

Give the Hook a clear API

  • The name must start with use followed by a capital letter.
  • A Hook may return an array, an object, or a single value.
  • A Hook may accept arguments, so each call site can configure its own behavior.
  • A function that calls no Hooks should not use the use prefix.

Return the smallest surface callers actually use. A focused name like useToggle is clearer than a generic wrapper around one Hook. Custom Hooks often wrap Effects too, which hides browser subscriptions and timers behind a simple name.

Keep extraction optional

Do not extract a Hook for every small duplicate. When the copied part is one line of state and the components stay readable, duplication is fine.

Extract when the logic is nontrivial, repeated in at least two places, and benefits from one shared implementation. The Hook body re-runs on every render, so keep it pure and free of side effects. A Hook that earns its name does one clear job.

The same Hook in two components still gives each one its own state. Read why hook order must stay stable and what sharing logic means when state stays independent.

Rune AI

Rune AI

Key Insights

  • A custom Hook is a function whose name starts with use and that calls other Hooks.
  • Move repeated stateful logic, not repeated markup, into the Hook.
  • Every call to the same Hook creates independent state.
  • Return only the values and actions callers actually need.
  • Skip the use prefix for functions that do not call Hooks.
RunePowered by Rune AI

Frequently Asked Questions

What is a custom Hook in React?

A custom Hook is a JavaScript function whose name starts with use and that calls other Hooks. It moves stateful logic out of a component so other components can reuse it.

Do custom Hooks share state between components?

No. Each call to a custom Hook creates independent state, so two components using the same Hook each get their own copy of the values it returns.

Does every function named with use have to call a Hook?

A function should only carry the use prefix if it calls at least one Hook, or if you plan to add Hook calls soon. Otherwise, keep it a normal function.

Conclusion

A custom Hook is a plain JavaScript function that follows the use naming rule and calls other Hooks. Extract one when the same stateful logic appears in more than one component, and keep its return API small enough to be obvious.