Build accessible React UIs with function components, hooks, derived state, and effect discipline; fix Strict Mode double-invoke, list keys, and concurrent rendering pitfalls. Use for components, forms, and client islands in Next.js or SPA apps.
Installs into .claude/skills of the current project.
Are you the author of React?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/alivirgo-react)
---
name: react
description: "Build accessible React UIs with function components, hooks, derived state, and effect discipline; fix Strict Mode double-invoke, list keys, and concurrent rendering pitfalls. Use for components, forms, and client islands in Next.js or SPA apps."
category: development
risk: safe
source: self
source_type: self
date_added: "2026-08-26"
tags: ["react", "hooks", "components", "frontend", "a11y", "react-19", "claude"]
tools: ["claude", "cursor", "gemini", "codex"]
---
# React UI Engineering AI Skill Guide (Claude)
## Overview & Engine Architecture
React renders a **component tree** of functions returning UI. **State updates** schedule re-renders; **hooks** attach state, context, refs, and effects. React 18+ **Concurrent** features and React 19 refinements (Actions, `use`, document metadata hooks in frameworks) change how async and transitions behave—effects still run after paint; **Strict Mode** double-invokes effects in development to surface missing cleanup.
Claude operates as a Principal UI Engineer: **pure render logic**, **minimal effects**, **accessible controls**, and **stable list identity**.
```
Render (derive from props/state)
→ commit DOM
→ useLayoutEffect (sync after DOM)
→ useEffect (async after paint)
```
---
## When to use / when not to
**Use when**
- Building interactive UI, forms, and client islands (`"use client"` in Next.js).
- Refactoring prop drilling into composition or colocated context.
- Fixing infinite loops, stale closures, and a11y failures.
**Do not use when**
- All data and interactivity can stay on the server (Next.js Server Components)—avoid unnecessary client bundles.
- Global state library migration is a team process—don't introduce Redux/Zustand without convention.
---
## Operational Capabilities & Agent Directives
1. **Derive during render**—don't mirror props into state (`fullName = first + last`).
2. **Effects for external sync only** (subscriptions, imperative DOM, analytics)—not for transforming props to state.
3. **Dependency arrays must be honest**; exhaustive-deps lint is your friend.
4. **Keys**: Stable unique IDs for reorderable lists—never index-as-key when order changes.
5. **Accessibility**: Real `<button>`, `<label htmlFor>`, keyboard focus; don't click-only `<div>`.
6. **React 19 / Actions**: Prefer `useTransition` + server actions (in Next) for mutations instead of manual loading flags when appropriate.
7. **Don't fetch in useEffect** for initial page data when a server layer exists (`@nextjs`).
---
## Patterns
Controlled input:
```tsx
function Search({ value, onChange }: { value: string; onChange: (v: string) => void }) {
return (
<label>
Search
<input value={value} onChange={(e) => onChange(e.target.value)} />
</label>
);
}
```
Functional updates (avoid stale state):
```tsx
setCount((c) => c + 1);
```
---
## Technical Troubleshooting Matrix
| Bug | Cause | Fix |
| --- | --- | --- |
| Infinite re-render | Effect sets state that retriggers effect | Remove cycle; derive |
| Stale handler | Missing deps | Fix deps or functional updates |
| Lost focus | Unstable keys remount subtree | Stable keys on list items |
| Double fetch in dev | Strict Mode | Ensure idempotent effects + cleanup |
| Hydration error | Server HTML ≠ client first render | Gate client-only UI with `useEffect` or suppress only when safe |
| "Cannot update during render" | setState in render body | Move to event handler/effect |
---
## Best practices
- Colocate state at lowest common ancestor.
- Error boundaries for recoverable regions.
- Test with Testing Library (`getByRole`, `getByLabelText`).
- Side effects and network mutations: dedicated hooks or server layer.
- Memoize (`useMemo`, `useCallback`) only when profiling shows cost.
---
## Limitations
- React doesn't include routing, data fetching, or CSS strategy—framework choices matter.
- Concurrent rendering can interrupt renders—avoid non-idempotent render side effects.
- Server Components (Next.js) cannot use most hooks—split client boundaries.
---
## Related skills
- `@nextjs` — RSC vs client boundaries
- `@typescript` — prop and hook typing
- `@vitest` — component unit tests
- `@playwright` — E2E behavior
---
## Agent Operational Directive
> **MANDATORY**: Prefer derived state over effect-synced state. Fix effect dependency bugs instead of disabling lint. Use semantic HTML and role-based queries in tests. Do not mark entire apps `"use client"` to avoid thinking about server boundaries.
---
## Sources
- [React docs](https://react.dev/) — hooks, Strict Mode, useEffect
- React 19 release notes — Actions, concurrent updates