# Custom Hooks — React

Source: https://www.skillbyai.com/en/react/h-custom

> Reuse stateful logic, not state.

## Functions that call hooks

A **custom hook** is a function whose name starts with `use` and that calls other hooks. It packages reusable logic: toggles, form fields, media queries, online status, fetching. Each component that calls the hook gets its **own** state; hooks share logic, not data. Return what callers need (values and functions), keep the API small, and test hooks through components that use them.

## A useToggle hook used by two components, run

I ran this with React 19.3 and react-dom 19.3 on Node.js 22, compiling JSX with esbuild 0.28. Browser-style examples use jsdom 29 as a fake DOM (imported from a small setup-dom.mjs file) and act() to apply updates. Two FAQ items use the same useToggle hook. Clicking only the first question opens only its answer: each component instance keeps its own state.

```jsx
import "./setup-dom.mjs";   // test setup: jsdom provides a browser-like DOM in Node
import { useState, useCallback, act } from "react";
import { createRoot } from "react-dom/client";

function useToggle(initial = false) {
  const [on, setOn] = useState(initial);
  const toggle = useCallback(() => setOn(v => !v), []);
  return [on, toggle];
}
function FAQ({ q, a }) {
  const [open, toggle] = useToggle();
  return <div><button onClick={toggle}>{q}</button>{open && <p>{a}</p>}</div>;
}
const root = createRoot(document.getElementById("root"));
await act(() => root.render(<><FAQ q="Refunds?" a="Within 14 days." /><FAQ q="Shipping?" a="3-5 days." /></>));
const [first] = document.querySelectorAll("button");
await act(() => first.click());
console.log([...document.querySelectorAll("p")].map(p => p.textContent));   // each FAQ has its own state
```

Output:

```
[ 'Within 14 days.' ]
```

## Name hooks after what they do

useOnlineStatus, useDebouncedValue and useCart say what they provide; vague names like useData hide intent.

**Quiz:** Do two components using the same custom hook share its state?

- [x] No, each call gets its own independent state
- [ ] Yes, always
- [ ] Only on the server
- [ ] Only if they are siblings

*Answer:* No, each call gets its own independent state. Hooks share logic, not state.
