React

Verified against Claude Code · 2026-07-14

Extract a reusable hook from tangled component logic

Pulls one piece of stateful logic out of a component into a properly named custom hook with a minimal, typed return contract, without changing runtime behavior.

Claude CodeCursorGitHub Copilot ChatChatGPT

The prompt

Ready to copy — highlighted parts are example details you can swap.

<role>
You are a senior React engineer extracting a custom hook from an existing component without changing its runtime behavior.
</role>

<component>
function ProductSearch() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); useEffect(() => { const id = setTimeout(() => fetch("/api/search?q=" + query).then(r => r.json()).then(setResults), 300); return () => clearTimeout(id); }, [query]); return (...); }
</component>

<extraction_target>
Pull out the logic responsible for: the debounced search input state and the effect that fires the API call and stores the results
</extraction_target>

<rules>
- Name the hook use<Something> based on what it does, not how it's implemented (useDebouncedSearch, not useStateAndEffect).
- The hook's return value must be a small, explicit object or tuple — nothing in the component should need to reach into unrelated state to make sense of it.
- Preserve every dependency array exactly as-is unless you can name the specific stale-closure or missing-dependency bug the current array causes.
- Do not introduce new state to "clean up" the API if the component genuinely needs the old shape — this is an extraction, not a redesign.
- If the logic depends on something specific to this one component (a prop name, a DOM ref only this component has), leave a TODO noting what would need to become a parameter to make the hook truly reusable elsewhere.
</rules>

<output_format>
1. The new hook, in its own code block, with a one-line comment above it stating its contract (inputs → outputs).
2. The component's render body, updated to call the hook instead of containing the extracted logic — nothing else in the component should change.
3. A short note on anything you deliberately left component-specific, per the TODO rule above.
</output_format>
Customize the highlighted detailsoptional — the prompt above already works

Why this works

The use<Something>-by-behavior naming rule forces the model to think about the hook's contract before its implementation, which is the actual difference between a genuinely reusable hook and a chunk of code that was just moved to a new file. Preserving the dependency array unless a specific bug is named stops a common failure mode where an LLM "fixes" a useEffect dependency array during an unrelated extraction and silently changes when the effect fires. The mandatory TODO for component-specific coupling matters because the biggest lie in hook extraction is pretending something is generic when it still reads a prop only the original component has — naming that explicitly is what lets a future reader actually reuse the hook instead of copy-pasting it and hoping.

What you get back

function useDebouncedSearch(delay = 300) { // Inputs: none. Outputs: { query, setQuery, results }. const [query, setQuery] = useState(''); const [results, setResults] = useState([]); useEffect(() => { const id = setTimeout(() => { fetch('/api/search?q=' + query).then(r => r.json()).then(setResults); }, delay); return () => clearTimeout(id); }, [query, delay]); return { query, setQuery, results }; } function ProductSearch() { const { query, setQuery, results } = useDebouncedSearch(); return (/* unchanged JSX */); } Note: no component-specific coupling found — this hook is reusable as-is.

Verified against

Claude Code Sonnet 4.6 · 2026-07-14

Cursor 2.1 · 2026-07-20

Changelog

  • 2026-07-14 Initial publish, verified against Claude Code (Sonnet 4.6) and Cursor 2.1.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All React prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY