[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71DA084TD9WEW07QP9PXDH4":3,"skill-same:01M71DA084TD9WEW07QP9PXDH4":131},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":6,"ownerHtmlUrl":63,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":64,"install":65,"resources":78},"01M71DA084TD9WEW07QP9PXDH4","best-practices-react",null,"React, Next.js, React Native, and web design best practices from Vercel Engineering.\nUse when writing, reviewing, or refactoring React\u002FNext.js\u002FReact Native components,\noptimizing performance, auditing UI accessibility, or designing component APIs.\nTriggers: \"review react\", \"optimize component\", \"check accessibility\", \"react best practices\",\n\"component architecture\", \"react native performance\".","cateyephotos\u002Fagent-skills","cateyephotos","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F110843613?v=4","01M71CCSDD8VJ7CZ4V1QQGBMA7","01M71CCSE1VRT329KB810CRC0V",0,"MIT","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"best practices react","best practices","react","react component","check","Next.js","use","best-practices","triggers","ui","react best practices","typescript","refactoring","component","react native","architecture","components","writing","component architecture","design","2026-11-10 10:12:30",false,"---\nname: best-practices-react\ndescription: |\n  React, Next.js, React Native, and web design best practices from Vercel Engineering.\n  Use when writing, reviewing, or refactoring React\u002FNext.js\u002FReact Native components,\n  optimizing performance, auditing UI accessibility, or designing component APIs.\n  Triggers: \"review react\", \"optimize component\", \"check accessibility\", \"react best practices\",\n  \"component architecture\", \"react native performance\".\ntriggers:\n  - best practices react\n  - react review\n  - react component\n  - next.js\n  - react native\n  - component architecture\nlicense: MIT\nmetadata:\n  author: vercel\n  version: \"1.0.0\"\n  language: typescript\n\nprovides:\n  - best-practices-react\ncomposes:\n  - task-monitor\n---\n\n# React Best Practices Collection\n\nEnterprise-grade React\u002FNext.js\u002FReact Native rules from Vercel Engineering. 100+ rules across 4 sub-skills with impact-prioritized categories.\n\n## Sub-Skills\n\n| Sub-Skill | Rules | Focus |\n|-----------|-------|-------|\n| `react-best-practices` | 40+ | React\u002FNext.js performance optimization |\n| `web-design-guidelines` | 100+ | Accessibility, forms, animation, dark mode, i18n |\n| `react-native-skills` | 16 | Mobile performance, animations, platform APIs |\n| `composition-patterns` | 8+ | Component architecture, prop design, compound components |\n\n## When to Use\n\n- **react-best-practices**: Writing React components, Next.js pages, data fetching, bundle optimization\n- **web-design-guidelines**: UI review, accessibility audit, design compliance, UX check\n- **react-native-skills**: React Native\u002FExpo apps, mobile performance, native modules\n- **composition-patterns**: Refactoring boolean prop proliferation, building component libraries\n\n## Quick Reference\n\n### Critical Impact — NON-NEGOTIABLE\n\nEvery interactive element gets **4 things at write time** — no exceptions, no retrofitting:\n\n1. **`data-qid`** — stable CSS selector. Format: `component:element:qualifier` (colon-separated). Used by test manifests, CDP automation, and `verify-data-qid.py` enforcement.\n2. **`data-qs-action`** — QuerySpec action ID for agent\u002Fvoice execution. Format: `COMPONENT_ACTION` (uppercase, underscore). An agent resolves NL intent → action ID → `document.querySelector('[data-qs-action=\"APPROVE_ENTRY\"]').click()` — zero latency, no database lookup, works offline.\n3. **`title`** — human-readable label. Required for MIL-STD-1472H compliance, screen readers, tooltips.\n4. **`useRegisterAction`** — registers the action to ArangoDB `app_actions` collection for training data, analytics, and cross-app action discovery.\n\nComponents without all 4 are **not shippable**. `verify-data-qid.py` enforces `data-qid` coverage in CI.\n\n**Write-time checklist:**\n```tsx\n\u003Cbutton\n  data-qid=\"quarantine:action:approve\"\n  data-qs-action=\"QUARANTINE_APPROVE\"\n  title=\"Approve selected entry\"\n  onClick={() => handleAction(id, 'approve')}\n>\n  Approve\n\u003C\u002Fbutton>\n\n\u002F\u002F In component body (registers to ArangoDB app_actions for training flywheel):\nuseRegisterAction('quarantine:action:approve', {\n  app: 'datalake-explorer',\n  action: 'QUARANTINE_APPROVE',\n  label: 'Approve',\n  description: 'Approve quarantined entry and remove from queue',\n})\n```\n\n**Why both `data-qs-action` AND `useRegisterAction`?**\n- `data-qs-action` = runtime DOM introspection (agent clicks the element, zero latency)\n- `useRegisterAction` = ArangoDB registry (training data, cross-app discovery, analytics)\n- They use the SAME action ID (`QUARANTINE_APPROVE`) so intent → action → DOM click is one straight line\n\n**Enforcement**: `verify-data-qid.py` MUST run in CI and `\u002Fplan` DoD for any UX task. Exit 1 = not shippable. `\u002Freview-plan` MUST FAIL any UX plan without it.\n- Eliminate request waterfalls (parallel fetching, `Promise.all`)\n- Bundle size (dynamic imports, tree shaking, barrel file avoidance)\n- Accessibility (aria-labels, semantic HTML, keyboard navigation)\n- FlashList over FlatList (React Native)\n\n### High Impact\n- Server-side rendering and streaming\n- Focus states (`focus-visible` patterns)\n- Layout (flex patterns, safe areas)\n- Animation (Reanimated, `prefers-reduced-motion`)\n\n### Medium Impact\n- Re-render optimization (`useMemo`, `useCallback`, React Compiler)\n- Forms (autocomplete, validation, error handling)\n- Dark mode (`color-scheme`, `theme-color` meta)\n- State management (Zustand patterns)\n\n## File Structure\n\n```\nbest-practices-react\u002F\n├── SKILL.md                          # This file\n├── README.md                         # Detailed sub-skill descriptions\n├── CLAUDE.md                         # Agent guidance (skill creation)\n├── skills\u002F\n│   ├── react-best-practices\u002F         # React\u002FNext.js performance rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F                    # Atomic rule files\n│   ├── web-design-guidelines\u002F        # UI\u002FUX\u002Fa11y rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F\n│   ├── react-native-skills\u002F          # React Native\u002FExpo rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F\n│   ├── composition-patterns\u002F         # Component architecture rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F\n│   └── claude.ai\u002F\n│       └── vercel-deploy-claimable\u002F  # Vercel deployment skill\n└── packages\u002F\n    └── react-best-practices-build\u002F   # TypeScript build tooling\n```\n\n## Common Mistakes\n\n### WRONG: `useRegisterAction` inside JSX, `.map()`, or function params\n```tsx\n\u002F\u002F BROKEN — hook inside .map() callback (violates Rules of Hooks)\n{items.map((item) => {\n  useRegisterAction('list:item', { ... })  \u002F\u002F ← CRASH or silent failure\n  return \u003Cdiv>{item.name}\u003C\u002Fdiv>\n})}\n\n\u002F\u002F BROKEN — hook inside function parameter destructuring\nfunction MetaItem({\n  useRegisterAction('meta:item', { ... })  \u002F\u002F ← syntax error\n  label,\n  value,\n}: Props) { ... }\n```\n\n### RIGHT: `useRegisterAction` at top of component function body\n```tsx\nexport default function QuarantineView({ entries }: Props) {\n  \u002F\u002F Hooks FIRST — before any other code\n  useRegisterAction('quarantine:action:approve', { ... })\n  useRegisterAction('quarantine:action:reject', { ... })\n\n  const [selected, setSelected] = useState(null)\n  \u002F\u002F ... rest of component\n```\n**Why:** React hooks must be called at the top level of a function component. Mechanical instrumentation scripts that inject hooks by line number will place them inside JSX or callbacks. Always verify placement manually.\n\n### WRONG: Import paths verified only by `tsc --noEmit`\n```bash\nnpx tsc --noEmit  # exit 0 — \"TypeScript clean!\"\n# But Vite dev server shows: Failed to resolve import \"..\u002F..\u002F..\u002Fhooks\u002FuseRegisterAction\"\n```\n\n### RIGHT: Verify imports against the live Vite dev server\n```bash\n# TSC and Vite resolve paths differently. Always check Vite:\ncurl -s -o \u002Fdev\u002Fnull -w \"%{http_code}\" \"http:\u002F\u002Flocalhost:3002\u002Fsrc\u002Fcomponents\u002FMyComponent.tsx\"\n# 200 = compiles. 500 = broken import. Do this for EVERY modified file.\n```\n**Why:** `moduleResolution: \"bundler\"` in tsconfig means TSC skips resolution for some imports. Vite resolves them at serve time and will 500 on wrong relative paths. A file can pass `tsc --noEmit` and still crash in the browser.\n\n### WRONG: Test manifest generated from `grep` of TSX source files\n```bash\n# Grepping source finds 124 data-qid values. But 91 of them are inside\n# modals, dropdowns, and subcomponents that only render after user interaction.\ngrep -roh 'data-qid=\"[^\"]*\"' src\u002Fcomponents\u002F | sort -u  # ← 124 qids\n# Live DOM on page load has only 33. The other 91 don't exist yet.\n```\n\n### RIGHT: Generate test manifest from the live DOM via CDP\n```bash\n# Use \u002Ftest-interactions generate, or query the live DOM directly:\n.\u002Frun.sh generate --url \"http:\u002F\u002Flocalhost:3002\u002F#my-view\" --output manifest.json\n\n# Or via CDP JavaScript execution:\n# document.querySelectorAll('[data-qid]') on EACH tab\u002Fview state\n```\n**Why:** Components render conditionally. A `data-qid` in TSX source only exists in the DOM when that component is mounted. Test manifests must reflect what the user can actually see and click, not what exists in source code.\n\n### WRONG: Static `data-qid` on dynamic list items\n```tsx\n\u002F\u002F Every entry gets the same qid — selector matches multiple elements\n{entries.map(e => (\n  \u003Cdiv data-qid=\"quarantine:entry\" onClick={() => select(e.id)}>\n    {e.name}\n  \u003C\u002Fdiv>\n))}\n```\n\n### RIGHT: Dynamic `data-qid` with stable identifier\n```tsx\n{entries.map(e => (\n  \u003Cdiv data-qid={`quarantine:entry:${e.id}`} onClick={() => select(e.id)}>\n    {e.name}\n  \u003C\u002Fdiv>\n))}\n```\n**Why:** Test manifests need unique selectors. If 18 entries share `data-qid=\"quarantine:entry\"`, `querySelector` always hits the first one. Use the entity ID to make each qid unique. Note: dynamic qids change when data changes, so test manifests for list items must query the live DOM or use `:nth-child` fallbacks.\n\n### WRONG: Early return that hides chrome (filters, nav, controls) on empty state\n```tsx\n\u002F\u002F The entire component disappears — user can't switch filters to find entries\nif (!loading && entries.length === 0) {\n  return \u003Cdiv>Queue is empty\u003C\u002Fdiv>  \u002F\u002F ← filter buttons, layout controls GONE\n}\n```\n\n### RIGHT: Empty state renders inline inside the content area\n```tsx\nconst showEmptyState = !loading && entries.length === 0\n\nreturn (\n  \u003Cdiv>\n    \u003CFilterBar \u002F>     {\u002F* always visible *\u002F}\n    \u003CLayoutControls \u002F> {\u002F* always visible *\u002F}\n    {showEmptyState\n      ? \u003CEmptyMessage>No entries for this filter\u003C\u002FEmptyMessage>\n      : \u003CEntryList entries={filtered} \u002F>\n    }\n  \u003C\u002Fdiv>\n)\n```\n**Why:** Early returns that replace the whole component break interaction tests — filter\u002Flayout `data-qid` elements vanish from the DOM when the list is empty. The user also loses the ability to switch filters or change layout. Chrome (nav, filters, controls) must always render; only the content area should show empty state.\n\n### WRONG: Importing from barrel files that bundle the entire module\n```typescript\nimport { Button } from '@\u002Fcomponents';  \u002F\u002F barrel re-export, bundles everything\n```\n\n### RIGHT: Import directly from the component file\n```typescript\nimport { Button } from '@\u002Fcomponents\u002FButton';\n```\n\n### WRONG: Missing focus-visible styles on interactive elements\n```css\nbutton:focus { outline: 2px solid blue; }  \u002F* triggers on click too *\u002F\n```\n\n### RIGHT: Use focus-visible for keyboard-only focus indicators\n```css\nbutton:focus-visible { outline: 2px solid blue; }\n```\n\n### WRONG: Sequential data fetching (request waterfall)\n```typescript\nconst user = await fetchUser(id);\nconst posts = await fetchPosts(user.id);  \u002F\u002F waits for user first\n```\n\n### RIGHT: Parallel fetching with Promise.all\n```typescript\nconst [user, posts] = await Promise.all([fetchUser(id), fetchPosts(id)]);\n```\n","# React Best Practices Collection\n\nEnterprise-grade React\u002FNext.js\u002FReact Native rules from Vercel Engineering. 100+ rules across 4 sub-skills with impact-prioritized categories.\n\n## Sub-Skills\n\n| Sub-Skill | Rules | Focus |\n|-----------|-------|-------|\n| `react-best-practices` | 40+ | React\u002FNext.js performance optimization |\n| `web-design-guidelines` | 100+ | Accessibility, forms, animation, dark mode, i18n |\n| `react-native-skills` | 16 | Mobile performance, animations, platform APIs |\n| `composition-patterns` | 8+ | Component architecture, prop design, compound components |\n\n## When to Use\n\n- **react-best-practices**: Writing React components, Next.js pages, data fetching, bundle optimization\n- **web-design-guidelines**: UI review, accessibility audit, design compliance, UX check\n- **react-native-skills**: React Native\u002FExpo apps, mobile performance, native modules\n- **composition-patterns**: Refactoring boolean prop proliferation, building component libraries\n\n## Quick Reference\n\n### Critical Impact — NON-NEGOTIABLE\n\nEvery interactive element gets **4 things at write time** — no exceptions, no retrofitting:\n\n1. **`data-qid`** — stable CSS selector. Format: `component:element:qualifier` (colon-separated). Used by test manifests, CDP automation, and `verify-data-qid.py` enforcement.\n2. **`data-qs-action`** — QuerySpec action ID for agent\u002Fvoice execution. Format: `COMPONENT_ACTION` (uppercase, underscore). An agent resolves NL intent → action ID → `document.querySelector('[data-qs-action=\"APPROVE_ENTRY\"]').click()` — zero latency, no database lookup, works offline.\n3. **`title`** — human-readable label. Required for MIL-STD-1472H compliance, screen readers, tooltips.\n4. **`useRegisterAction`** — registers the action to ArangoDB `app_actions` collection for training data, analytics, and cross-app action discovery.\n\nComponents without all 4 are **not shippable**. `verify-data-qid.py` enforces `data-qid` coverage in CI.\n\n**Write-time checklist:**\n```tsx\n\u003Cbutton\n  data-qid=\"quarantine:action:approve\"\n  data-qs-action=\"QUARANTINE_APPROVE\"\n  title=\"Approve selected entry\"\n  onClick={() => handleAction(id, 'approve')}\n>\n  Approve\n\u003C\u002Fbutton>\n\n\u002F\u002F In component body (registers to ArangoDB app_actions for training flywheel):\nuseRegisterAction('quarantine:action:approve', {\n  app: 'datalake-explorer',\n  action: 'QUARANTINE_APPROVE',\n  label: 'Approve',\n  description: 'Approve quarantined entry and remove from queue',\n})\n```\n\n**Why both `data-qs-action` AND `useRegisterAction`?**\n- `data-qs-action` = runtime DOM introspection (agent clicks the element, zero latency)\n- `useRegisterAction` = ArangoDB registry (training data, cross-app discovery, analytics)\n- They use the SAME action ID (`QUARANTINE_APPROVE`) so intent → action → DOM click is one straight line\n\n**Enforcement**: `verify-data-qid.py` MUST run in CI and `\u002Fplan` DoD for any UX task. Exit 1 = not shippable. `\u002Freview-plan` MUST FAIL any UX plan without it.\n- Eliminate request waterfalls (parallel fetching, `Promise.all`)\n- Bundle size (dynamic imports, tree shaking, barrel file avoidance)\n- Accessibility (aria-labels, semantic HTML, keyboard navigation)\n- FlashList over FlatList (React Native)\n\n### High Impact\n- Server-side rendering and streaming\n- Focus states (`focus-visible` patterns)\n- Layout (flex patterns, safe areas)\n- Animation (Reanimated, `prefers-reduced-motion`)\n\n### Medium Impact\n- Re-render optimization (`useMemo`, `useCallback`, React Compiler)\n- Forms (autocomplete, validation, error handling)\n- Dark mode (`color-scheme`, `theme-color` meta)\n- State management (Zustand patterns)\n\n## File Structure\n\n```\nbest-practices-react\u002F\n├── SKILL.md                          # This file\n├── README.md                         # Detailed sub-skill descriptions\n├── CLAUDE.md                         # Agent guidance (skill creation)\n├── skills\u002F\n│   ├── react-best-practices\u002F         # React\u002FNext.js performance rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F                    # Atomic rule files\n│   ├── web-design-guidelines\u002F        # UI\u002FUX\u002Fa11y rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F\n│   ├── react-native-skills\u002F          # React Native\u002FExpo rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F\n│   ├── composition-patterns\u002F         # Component architecture rules\n│   │   ├── SKILL.md\n│   │   └── rules\u002F\n│   └── claude.ai\u002F\n│       └── vercel-deploy-claimable\u002F  # Vercel deployment skill\n└── packages\u002F\n    └── react-best-practices-build\u002F   # TypeScript build tooling\n```\n\n## Common Mistakes\n\n### WRONG: `useRegisterAction` inside JSX, `.map()`, or function params\n```tsx\n\u002F\u002F BROKEN — hook inside .map() callback (violates Rules of Hooks)\n{items.map((item) => {\n  useRegisterAction('list:item', { ... })  \u002F\u002F ← CRASH or silent failure\n  return \u003Cdiv>{item.name}\u003C\u002Fdiv>\n})}\n\n\u002F\u002F BROKEN — hook inside function parameter destructuring\nfunction MetaItem({\n  useRegisterAction('meta:item', { ... })  \u002F\u002F ← syntax error\n  label,\n  value,\n}: Props) { ... }\n```\n\n### RIGHT: `useRegisterAction` at top of component function body\n```tsx\nexport default function QuarantineView({ entries }: Props) {\n  \u002F\u002F Hooks FIRST — before any other code\n  useRegisterAction('quarantine:action:approve', { ... })\n  useRegisterAction('quarantine:action:reject', { ... })\n\n  const [selected, setSelected] = useState(null)\n  \u002F\u002F ... rest of component\n```\n**Why:** React hooks must be called at the top level of a function component. Mechanical instrumentation scripts that inject hooks by line number will place them inside JSX or callbacks. Always verify placement manually.\n\n### WRONG: Import paths verified only by `tsc --noEmit`\n```bash\nnpx tsc --noEmit  # exit 0 — \"TypeScript clean!\"\n# But Vite dev server shows: Failed to resolve import \"..\u002F..\u002F..\u002Fhooks\u002FuseRegisterAction\"\n```\n\n### RIGHT: Verify imports against the live Vite dev server\n```bash\n# TSC and Vite resolve paths differently. Always check Vite:\ncurl -s -o \u002Fdev\u002Fnull -w \"%{http_code}\" \"http:\u002F\u002Flocalhost:3002\u002Fsrc\u002Fcomponents\u002FMyComponent.tsx\"\n# 200 = compiles. 500 = broken import. Do this for EVERY modified file.\n```\n**Why:** `moduleResolution: \"bundler\"` in tsconfig means TSC skips resolution for some imports. Vite resolves them at serve time and will 500 on wrong relative paths. A file can pass `tsc --noEmit` and still crash in the browser.\n\n### WRONG: Test manifest generated from `grep` of TSX source files\n```bash\n# Grepping source finds 124 data-qid values. But 91 of them are inside\n# modals, dropdowns, and subcomponents that only render after user interaction.\ngrep -roh 'data-qid=\"[^\"]*\"' src\u002Fcomponents\u002F | sort -u  # ← 124 qids\n# Live DOM on page load has only 33. The other 91 don't exist yet.\n```\n\n### RIGHT: Generate test manifest from the live DOM via CDP\n```bash\n# Use \u002Ftest-interactions generate, or query the live DOM directly:\n.\u002Frun.sh generate --url \"http:\u002F\u002Flocalhost:3002\u002F#my-view\" --output manifest.json\n\n# Or via CDP JavaScript execution:\n# document.querySelectorAll('[data-qid]') on EACH tab\u002Fview state\n```\n**Why:** Components render conditionally. A `data-qid` in TSX source only exists in the DOM when that component is mounted. Test manifests must reflect what the user can actually see and click, not what exists in source code.\n\n### WRONG: Static `data-qid` on dynamic list items\n```tsx\n\u002F\u002F Every entry gets the same qid — selector matches multiple elements\n{entries.map(e => (\n  \u003Cdiv data-qid=\"quarantine:entry\" onClick={() => select(e.id)}>\n    {e.name}\n  \u003C\u002Fdiv>\n))}\n```\n\n### RIGHT: Dynamic `data-qid` with stable identifier\n```tsx\n{entries.map(e => (\n  \u003Cdiv data-qid={`quarantine:entry:${e.id}`} onClick={() => select(e.id)}>\n    {e.name}\n  \u003C\u002Fdiv>\n))}\n```\n**Why:** Test manifests need unique selectors. If 18 entries share `data-qid=\"quarantine:entry\"`, `querySelector` always hits the first one. Use the entity ID to make each qid unique. Note: dynamic qids change when data changes, so test manifests for list items must query the live DOM or use `:nth-child` fallbacks.\n\n### WRONG: Early return that hides chrome (filters, nav, controls) on empty state\n```tsx\n\u002F\u002F The entire component disappears — user can't switch filters to find entries\nif (!loading && entries.length === 0) {\n  return \u003Cdiv>Queue is empty\u003C\u002Fdiv>  \u002F\u002F ← filter buttons, layout controls GONE\n}\n```\n\n### RIGHT: Empty state renders inline inside the content area\n```tsx\nconst showEmptyState = !loading && entries.length === 0\n\nreturn (\n  \u003Cdiv>\n    \u003CFilterBar \u002F>     {\u002F* always visible *\u002F}\n    \u003CLayoutControls \u002F> {\u002F* always visible *\u002F}\n    {showEmptyState\n      ? \u003CEmptyMessage>No entries for this filter\u003C\u002FEmptyMessage>\n      : \u003CEntryList entries={filtered} \u002F>\n    }\n  \u003C\u002Fdiv>\n)\n```\n**Why:** Early returns that replace the whole component break interaction tests — filter\u002Flayout `data-qid` elements vanish from the DOM when the list is empty. The user also loses the ability to switch filters or change layout. Chrome (nav, filters, controls) must always render; only the content area should show empty state.\n\n### WRONG: Importing from barrel files that bundle the entire module\n```typescript\nimport { Button } from '@\u002Fcomponents';  \u002F\u002F barrel re-export, bundles everything\n```\n\n### RIGHT: Import directly from the component file\n```typescript\nimport { Button } from '@\u002Fcomponents\u002FButton';\n```\n\n### WRONG: Missing focus-visible styles on interactive elements\n```css\nbutton:focus { outline: 2px solid blue; }  \u002F* triggers on click too *\u002F\n```\n\n### RIGHT: Use focus-visible for keyboard-only focus indicators\n```css\nbutton:focus-visible { outline: 2px solid blue; }\n```\n\n### WRONG: Sequential data fetching (request waterfall)\n```typescript\nconst user = await fetchUser(id);\nconst posts = await fetchPosts(user.id);  \u002F\u002F waits for user first\n```\n\n### RIGHT: Parallel fetching with Promise.all\n```typescript\nconst [user, posts] = await Promise.all([fetchUser(id), fetchPosts(id)]);\n```\n",{"name":5,"license":14,"composes":48,"metadata":50,"provides":53,"triggers":54,"description":57},[49],"task-monitor",{"author":51,"version":52,"language":34},"vercel","1.0.0",[5],[23,55,26,56,37,41],"react review","next.js","React, Next.js, React Native, and web design best practices from Vercel Engineering.\nUse when writing, reviewing, or refactoring React\u002FNext.js\u002FReact Native components,\noptimizing performance, auditing UI accessibility, or designing component APIs.\nTriggers: \"review react\", \"optimize component\", \"check accessibility\", \"react best practices\",\n\"component architecture\", \"react native performance\".\n","main","92d3cf5de96f8f7e1668e121e82a95faaa78a995","skills\u002Fbest-practices-react",2,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills","https:\u002F\u002Fgithub.com\u002Fcateyephotos","2026-06-13 12:05:20",{"source":8,"skillName":5,"commands":66,"prompt":76,"zipAvailable":77},[67,70,73],{"tool":68,"command":69},"npx","npx skills add cateyephotos\u002Fagent-skills --skill best-practices-react",{"tool":71,"command":72},"bunx","bunx skills add cateyephotos\u002Fagent-skills --skill best-practices-react",{"tool":74,"command":75},"pnpm","pnpm dlx skills add cateyephotos\u002Fagent-skills --skill best-practices-react","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002FSKILL.md",true,[79,85,89,93,97,103,107,111,115,119,123,127],{"path":80,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":83,"sourceHtmlUrl":84},".github\u002Fworkflows\u002Freact-best-practices-ci.yml","REFERENCE","参考文档",822,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002F.github\u002Fworkflows\u002Freact-best-practices-ci.yml",{"path":86,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":87,"sourceHtmlUrl":88},"docs\u002FAGENTS.md",3281,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fdocs\u002FAGENTS.md",{"path":90,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":91,"sourceHtmlUrl":92},"docs\u002FREADME.md",4586,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fdocs\u002FREADME.md",{"path":94,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":95,"sourceHtmlUrl":96},"packages\u002Freact-best-practices-build\u002Fpnpm-lock.yaml",10270,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fpnpm-lock.yaml",{"path":98,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":101,"sourceHtmlUrl":102},"packages\u002Freact-best-practices-build\u002Fsrc\u002Fbuild.ts","SCRIPT","脚本",9972,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Fbuild.ts",{"path":104,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":105,"sourceHtmlUrl":106},"packages\u002Freact-best-practices-build\u002Fsrc\u002Fconfig.ts",2902,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Fconfig.ts",{"path":108,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":109,"sourceHtmlUrl":110},"packages\u002Freact-best-practices-build\u002Fsrc\u002Fextract-tests.ts",2455,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Fextract-tests.ts",{"path":112,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":113,"sourceHtmlUrl":114},"packages\u002Freact-best-practices-build\u002Fsrc\u002Fmigrate.ts",5547,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Fmigrate.ts",{"path":116,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":117,"sourceHtmlUrl":118},"packages\u002Freact-best-practices-build\u002Fsrc\u002Fparser.ts",7850,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Fparser.ts",{"path":120,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":121,"sourceHtmlUrl":122},"packages\u002Freact-best-practices-build\u002Fsrc\u002Ftypes.ts",1337,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Ftypes.ts",{"path":124,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":125,"sourceHtmlUrl":126},"packages\u002Freact-best-practices-build\u002Fsrc\u002Fvalidate.ts",3537,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fpackages\u002Freact-best-practices-build\u002Fsrc\u002Fvalidate.ts",{"path":128,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":129,"sourceHtmlUrl":130},"sanity.sh",1309,"https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fsanity.sh",[132,157,185,213,230,245],{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":43},"01M71DBADHWPBVJWYQT9VAD1XE","best-practices-streamdeck","Project-specific best practices for the Stream Deck control suite: icon format constraints, socket vs config boundaries, widget button lifecycle, page creation via build_page, ArangoDB fallback patterns, and NVIS palette compliance.","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-streamdeck\u002FSKILL.md",[],[24,139,140,141,142,143,144,145,146,147,148,149,30,150,151,152,153,154,155,156],"best practices streamdeck","creation","for","project","page","static","deck","socket","lifecycle","monitor","typer","icon","task","palette","control","native","via","build",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":166,"publishedAt":43},"01M71DARX9YN0QEXS6EM2C6E4X","best-practices-scillm","Error recovery and anti-patterns for scillm LLM proxy. Load this when scillm calls fail, timeout, or return unexpected results. Covers batch sizing, header requirements, model selection, and debugging workflow.","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-scillm\u002FSKILL.md",[163],{"categoryNo":164,"categoryName":165,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[167,24,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,141],"best practices scillm","scillm","error","processing","model","selection","model selection","error recovery","debugging","when","workflow","batch","anti-patterns","rate","rate limit","patterns","limit","proxy",{"skillNo":186,"name":187,"nameZh":6,"description":188,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":189,"categories":190,"keywords":194,"publishedAt":43},"01M71DAMV3PAAPBADP5EY1N61S","best-practices-rust","Repo-specific Rust best practices for agentic coding: thiserror + anyhow error handling, tokio async runtime, tracing for observability, clap for CLI, axum for HTTP, serde patterns, cargo workspace conventions, ownership and lifetimes, and idiomatic Rust 2024 edition patterns.","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-rust\u002FSKILL.md",[191],{"categoryNo":192,"categoryName":193,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000007","代码审查",[195,196,24,169,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212],"rust","best practices rust","async runtime","tokio","performance","code review","2024","agentic","code","review","resilience","server","cli","axum","rust error handling","polars","rust best practices","tracing",{"skillNo":214,"name":215,"nameZh":6,"description":216,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":217,"categories":218,"keywords":220,"publishedAt":43},"01M71DACXQ43RCTYYCB8WB1KPG","react-native-skills","React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fskills\u002Freact-native-skills\u002FSKILL.md",[219],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[25,37,154,221,222,223,224,141,199,51,225,31,29,226,227,176,24,228,39,229],"react native skills","modules","platform","animations","implementing","react native components","apps","tasks","with",{"skillNo":231,"name":232,"nameZh":6,"description":233,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":234,"categories":235,"keywords":237,"publishedAt":43},"01M71DA9YZ05NTRPEK9JAX283K","react-best-practices","React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React\u002FNext.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fskills\u002Freact-best-practices\u002FSKILL.md",[236],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[25,33,24,199,40,176,203,228,39,238,239,240,35,241,182,242,51,243,31,244],"data fetching","react components","next","data","Optimization","guidelines","pages",{"skillNo":246,"name":247,"nameZh":6,"description":248,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":249,"categories":250,"keywords":252,"publishedAt":43},"01M71DA77CYKDT0Q7VAXG4Y9QW","composition-patterns","React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.","https:\u002F\u002Fgithub.com\u002Fcateyephotos\u002Fagent-skills\u002Fblob\u002Fmain\u002Fskills\u002Fbest-practices-react\u002Fskills\u002Fcomposition-patterns\u002FSKILL.md",[251],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[253,254,182,255,256,51,257,31,258,41,29,176,259,228,39,38,260,261,25,229],"Composition","composition patterns","react composition patterns","react 19","render","boolean","reusable","react composition","api"]