React Hooks Pattern
Reuse stateful logic across components via custom hooks
When to Use
- Multiple components share the same stateful logic (e.g., data fetching, form state, media queries)
- You want to extract complex logic from a component to improve readability
- You need to compose behaviors without inheritance or render props
- You are using React 16.8+ (hooks are unavailable in class components)
Instructions
- Identify repeated stateful logic across two or more components.
- Extract it into a function prefixed with
use (e.g., useWindowSize, useFetch, useForm).
- The custom hook must call at least one built-in hook (
useState, useEffect, useCallback, etc.).
- Return only what the consumer needs — avoid over-exposing internal state.
- Name the hook descriptively after its behavior, not its implementation (
useMediaQuery not useEventListener).
- Keep hooks pure and side-effect-free at the call site — effects belong inside
useEffect.
- Document the hook's return type with TypeScript interfaces.
- Co-locate the hook file with its primary consumer or in a
hooks/ directory.
// Good: descriptive name, typed return, minimal surface area
function useWindowSize(): { width: number; height: number } {
const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
useEffect(() => {
const handler = () => setSize({ width: window.innerWidth, height: window.innerHeight });
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
}, []);
return size;
}
Details
Custom hooks were introduced in React 16.8 to solve the code reuse problem that previously required higher-order components or render props. The key insight: hooks are just functions, and the use prefix is a convention that enables lint rules (react-hooks/rules-of-hooks) to enforce hook semantics.
Trade-offs:
- Hooks compose easily but debugging deep hook stacks can be harder than class-based patterns
- The
use naming convention is enforced by ESLint, not the runtime — calling a hook outside a component or another hook will cause runtime errors, not type errors
- React DevTools shows custom hook names in the component tree when they follow the
use prefix convention
When NOT to use:
- Logic that does not involve state or effects — extract as a plain utility function instead
- Logic specific to a single component that will never be reused
Related patterns:
- Provider Pattern — hooks often expose context via a
useXxx() wrapper
- Compound Pattern — hooks can manage shared state for compound component groups
Source
https://patterns.dev/react/hooks-pattern
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.
1---2name: react-hooks-pattern3description: React Hooks Pattern4---5# React Hooks Pattern67> Reuse stateful logic across components via custom hooks89## When to Use1011- Multiple components share the same stateful logic (e.g., data fetching, form state, media queries)12- You want to extract complex logic from a component to improve readability13- You need to compose behaviors without inheritance or render props14- You are using React 16.8+ (hooks are unavailable in class components)1516## Instructions17181. Identify repeated stateful logic across two or more components.192. Extract it into a function prefixed with `use` (e.g., `useWindowSize`, `useFetch`, `useForm`).203. The custom hook must call at least one built-in hook (`useState`, `useEffect`, `useCallback`, etc.).214. Return only what the consumer needs — avoid over-exposing internal state.225. Name the hook descriptively after its behavior, not its implementation (`useMediaQuery` not `useEventListener`).236. Keep hooks pure and side-effect-free at the call site — effects belong inside `useEffect`.247. Document the hook's return type with TypeScript interfaces.258. Co-locate the hook file with its primary consumer or in a `hooks/` directory.2627```typescript28// Good: descriptive name, typed return, minimal surface area29function useWindowSize(): { width: number; height: number } {30 const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });31 useEffect(() => {32 const handler = () => setSize({ width: window.innerWidth, height: window.innerHeight });33 window.addEventListener('resize', handler);34 return () => window.removeEventListener('resize', handler);35 }, []);36 return size;37}38```3940## Details4142Custom hooks were introduced in React 16.8 to solve the code reuse problem that previously required higher-order components or render props. The key insight: hooks are just functions, and the `use` prefix is a convention that enables lint rules (react-hooks/rules-of-hooks) to enforce hook semantics.4344**Trade-offs:**4546- Hooks compose easily but debugging deep hook stacks can be harder than class-based patterns47- The `use` naming convention is enforced by ESLint, not the runtime — calling a hook outside a component or another hook will cause runtime errors, not type errors48- React DevTools shows custom hook names in the component tree when they follow the `use` prefix convention4950**When NOT to use:**5152- Logic that does not involve state or effects — extract as a plain utility function instead53- Logic specific to a single component that will never be reused5455**Related patterns:**5657- Provider Pattern — hooks often expose context via a `useXxx()` wrapper58- Compound Pattern — hooks can manage shared state for compound component groups5960## Source6162https://patterns.dev/react/hooks-pattern6364## Process65661. Read the instructions and examples in this document.672. Apply the patterns to your implementation, adapting to your specific context.683. Verify your implementation against the details and edge cases listed above.6970## Harness Integration7172- **Type:** knowledge — this skill is a reference document, not a procedural workflow.73- **No tools or state** — consumed as context by other skills and agents.7475## Success Criteria7677- The patterns described in this document are applied correctly in the implementation.78- Edge cases and anti-patterns listed in this document are avoided.