react-hooks
Apply when managing state, side effects, context, or refs in React functional components. **React 19+ Note**: React 19.x introduced new hooks for forms/actions (useActionState, useOptimistic, useFormStatus) and effect events (useEffectEvent in 19.2). Core hooks (useState, useEffect, useCallback, etc.) remain unchanged.
When & Why to Use This Skill
This Claude skill provides expert-level patterns and best practices for managing state, side effects, and context in React functional components. It offers comprehensive guidance on core hooks and the latest React 19+ features, including useActionState and useEffectEvent, to ensure high-performance and maintainable frontend development.
Use Cases
- Implementing complex state logic and performance optimizations using core hooks like useState, useMemo, and useCallback.
- Managing asynchronous side effects and API integrations with robust useEffect cleanup and AbortController patterns.
- Modernizing React applications by adopting React 19+ form actions and optimistic UI updates for better user experiences.
- Creating reusable custom hooks to encapsulate shared business logic and promote modular architecture across the codebase.
- Identifying and refactoring common React anti-patterns such as missing dependencies, direct state mutation, or improper hook placement.
| name | react-hooks |
|---|---|
| description | Apply when managing state, side effects, context, or refs in React functional components. **React 19+ Note**: React 19.x introduced new hooks for forms/actions (useActionState, useOptimistic, useFormStatus) and effect events (useEffectEvent in 19.2). Core hooks (useState, useEffect, useCallback, etc.) remain unchanged. |
| version | 1.1.0 |
| tokens | ~1100 |
| confidence | high |
| - https | //react.dev/blog/2025/10/01/react-19-2 |
| react_version | "18.2+, 19.x" |
| last_validated | 2025-12-10 |
| next_review | 2025-01-24 |
| tags | [react, hooks, frontend, state] |
When to Use
Apply when managing state, side effects, context, or refs in React functional components.
React 19+ Note: React 19.x introduced new hooks for forms/actions (useActionState, useOptimistic, useFormStatus) and effect events (useEffectEvent in 19.2). Core hooks (useState, useEffect, useCallback, etc.) remain unchanged.
Patterns
Pattern 1: useState with Objects
// Source: https://react.dev/reference/react/useState
interface FormState {
name: string;
email: string;
}
const [form, setForm] = useState<FormState>({ name: '', email: '' });
// Update single field (immutable)
setForm(prev => ({ ...prev, name: 'John' }));
Pattern 2: useEffect Cleanup
// Source: https://react.dev/reference/react/useEffect
useEffect(() => {
const controller = new AbortController();
async function fetchData() {
const res = await fetch(url, { signal: controller.signal });
setData(await res.json());
}
fetchData();
return () => controller.abort(); // Cleanup
}, [url]);
Pattern 3: useCallback for Stable References
// Source: https://react.dev/reference/react/useCallback
const handleSubmit = useCallback((data: FormData) => {
onSubmit(data);
}, [onSubmit]); // Only recreate if onSubmit changes
// Use in child: <Form onSubmit={handleSubmit} />
Pattern 4: useMemo for Expensive Computations
// Source: https://react.dev/reference/react/useMemo
const sortedItems = useMemo(() => {
return items
.filter(item => item.active)
.sort((a, b) => a.name.localeCompare(b.name));
}, [items]); // Recompute only when items change
Pattern 5: Custom Hook Pattern
// Source: https://react.dev/learn/reusing-logic-with-custom-hooks
function useDebounce<T>(value: T, delay: number): T {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debounced;
}
// Usage
const debouncedSearch = useDebounce(searchTerm, 300);
Pattern 6: useRef for DOM Access
// Source: https://react.dev/reference/react/useRef
const inputRef = useRef<HTMLInputElement>(null);
const focusInput = () => {
inputRef.current?.focus();
};
return <input ref={inputRef} />;
Pattern 7: useActionState for Forms (React 19+)
// Source: https://react.dev/blog/2024/12/05/react-19
import { useActionState } from 'react';
async function submitForm(prevState: any, formData: FormData) {
const name = formData.get('name');
// Perform async operation
return { success: true, name };
}
function MyForm() {
const [state, action, isPending] = useActionState(submitForm, null);
return (
<form action={action}>
<input name="name" disabled={isPending} />
<button disabled={isPending}>Submit</button>
{state?.success && <p>Success: {state.name}</p>}
</form>
);
}
Pattern 8: useEffectEvent for Non-Reactive Logic (React 19.2+)
// Source: https://react.dev/reference/react/useEffectEvent
import { useEffect, useEffectEvent } from 'react';
function Chat({ roomId, theme }) {
// Event function always sees latest theme, but doesn't trigger effect
const onConnected = useEffectEvent(() => {
showNotification('Connected!', theme);
});
useEffect(() => {
const connection = createConnection(roomId);
connection.on('connected', onConnected);
connection.connect();
return () => connection.disconnect();
}, [roomId]); // Only re-run when roomId changes
}
Anti-Patterns
- Hooks in conditions/loops - Call hooks at top level only
- Missing dependencies - Include all values used in effect/callback
- Over-using useMemo/useCallback - Use only when performance matters (profile first)
- Mutating state directly - Always use setter, spread for objects/arrays
- Async function as useEffect callback - Define async function inside, then call it
Verification Checklist
- Hooks at component top level (not in conditions)
- All dependencies listed in dependency arrays
- useEffect has cleanup for subscriptions/timers
- Custom hooks start with
useprefix - No direct state mutation
- useEffectEvent excluded from dependency arrays (React 19.2+)