Use when designing, implementing, reviewing, debugging, testing, or shipping React web client features, including component structure, routing, state ownership, API/data fetching, forms, browser behavior, accessibility, performance, build/deploy, and rendered browser verification. Product-agnostic; use miniapp-product-dev for WeChat/Alipay/Douyin/Baidu mini-programs, app-cross-platform-dev for Flutter/React Native/Android/iOS apps, product-ui-ux-design for UI/UX rules, backend skills for serv...
Scanned 9/2/2026
Install to Claude Code
npx -y skills add ccoalm/ccl-skills --skill web-react-dev --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Web React Dev?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ccoalm-web-react-dev)More formats (shields.io, HTML) on the badges page.
---
name: web-react-dev
description: Use when designing, implementing, reviewing, debugging, testing, or shipping React web client features, including component structure, routing, state ownership, API/data fetching, forms, browser behavior, accessibility, performance, build/deploy, and rendered browser verification. Product-agnostic; use miniapp-product-dev for WeChat/Alipay/Douyin/Baidu mini-programs, app-cross-platform-dev for Flutter/React Native/Android/iOS apps, product-ui-ux-design for UI/UX rules, backend skills for services, and testing-strategy for test-layer planning. Triggers also include "用 React 实现这个前端", "React 组件怎么写", "React 写一个", "Tailwind 怎么写", "Next.js / Vite 项目配置", "重构这个 React 组件/页面(局部)", "refactor a React component/file".
---
# Web React Dev
Use this skill for React web client engineering. It covers browser-rendered React applications, React components, routing, data fetching, forms, frontend API integration, accessibility, performance, build, and deploy checks. It does not own mini-program host behavior, Flutter, native mobile, backend service design, or visual design system rules.
## Routing
- Use `product-rd-workflow` first when the work spans product, design, architecture, implementation, testing, review, and release.
- Use `product-ui-ux-design` before or alongside coding for interaction model, layout, visual hierarchy, density, states, and UI acceptance.
- Use `miniapp-product-dev` for WeChat/Alipay/Douyin/Baidu mini-program pages, host-platform APIs, developer tools, review submission, and release. For React/H5 embedded inside a mini-program webview, this skill owns the React page while `miniapp-product-dev` owns the mini-program shell, bridge, host capabilities, and review/release evidence.
- For Taro projects (React syntax compiled to mini-program runtime): this skill owns the React layer (component decomposition, hooks, state ownership, effect discipline, accessibility primitives) and the **pure** shared layer in the repo's established shared module: DTOs, types, validators, pure mapping functions.
- `miniapp-product-dev` owns Taro lifecycle hooks (`useReady`/`useLoad`/`useDidShow`/`useDidHide`), `Taro.*` runtime APIs, platform branching (`process.env.TARO_ENV`, conditional compilation, platform-specific files), subpackage configuration, host capability adapters, multi-target build invocation, host review/release, and rendered mini-program evidence.
- Shared **runtime adapters** that mini-program targets consume are co-owned with a named final-decision owner per adapter, recorded in the repo. The adapter list and the miniapp acceptance-gate enumeration are canonical in `miniapp-product-dev` (the `Shared runtime adapters consumed by mini-program targets` row under `## Sibling Boundary With web-react-dev`); that gate is blocking and its miniapp contract tests must pass before mini-program targets import the adapter. Web sets browser semantics and cannot merge an adapter change that is browser-safe but mini-program-unsafe. Do not re-add a fixed kill-switch dimension list here: the owner's safety contract names the property (`fail-closed flag evaluation`) and its release contract makes each host platform's gray-release mechanism its own contract, so the dimensions a given adapter needs come from that platform's contract, not from a list on this side. Before merging an adapter change, the merge record must carry the canonical row's gate token and a passing miniapp-contract run recorded on the change under merge (rule canonical in that row); a merge record without the token, or asserting mini-program-safety without the contract run, is a violation.
- When shared code must run in both web and mini-program targets, keep `react-dom`, DOM mutation, browser observers (`IntersectionObserver`/`ResizeObserver`/`MutationObserver`), RAF/layout APIs, and other browser globals out of the shared layer; use Taro cross-platform equivalents at the consumer side.
- Use `app-cross-platform-dev` for Flutter, React Native, native Android, native iOS, app store release, and device-native capability work.
- Use Go or Python backend skills for API/service ownership, persistence, auth services, queues, and server contracts.
- For backend HTTP integrations, preserve current client wire behavior unless an explicit consumer-migration decision exists. Classify JSON vs protobuf-backed HTTP using `../platform-service-connectivity/references/protobuf-http-contract-signals.md`.
- First decide whether the client diff touches the HTTP contract or wire behavior. Wire-unchanged UI/component/state work does not need a backend owner round-trip and must not claim backend contract conformance.
- For unrelated client work, classify the diff with the canonical gate. If the surface is out of scope, client work may continue without claiming backend contract conformance.
- If the canonical gate classifies the diff as in scope, confirm the backend's recorded wire format or route back to the backend contract owner.
- Routine JSON/OpenAPI changes use the existing API contract record and do not require backend wire-format confirmation when the canonical reference classifies the surface as out of the protobuf wire-format gate.
- Client API wrappers must consume the backend contract's recorded response envelope per `../platform-service-connectivity/references/http-response-envelope-contract.md`: for surfaces on the canonical `code`/`message`/`data` envelope, components and domain state read typed business data from `data`; other shipped or non-JSON envelopes are consumed per their recorded contract. Read only fields present in the recorded contract — do not infer business fields from unrecorded top-level or fallback shapes — and scatter no duplicate envelope parsing across the client.
- If backend wire-format evidence is unreachable for an in-scope surface, stop at `pending-contract-owner`, name the backend owner or owning repo, record the attempted lookup, and set the next escalation path. An assumed-wire-format note never unblocks merge. The blocker clears only when a checkable owner record, quoted prior backend record, or explicit migration decision is available; if no owner responds within the team's review SLA, keep the client change blocked or downscope the touched wire-format surface and record the dropped surface as an open owner-routed gap. Do not claim backend contract conformance or completion for the removed slice.
- Do not fork IDL or hand-maintain duplicated DTOs in the web repo.
- Use `testing-strategy` to choose unit/component/API/E2E layers; return here for React-specific implementation.
- Use `test-artifact-management` when the ask is about generating structured test cases from a Feishu requirements doc or codebase and tracking them in Feishu Bitable before implementation begins.
- Use `defect-diagnosis` first for failed tests, browser bugs, hydration/rendering issues, flaky UI, API integration symptoms, or production regressions.
- For money, quota, permission, tenant/user data, high-impact AI, repeated submit, async finality, or support-traceable incidents, apply `product-rd-workflow` high-risk resilience gates before treating the UI as complete.
## Core Workflow
Before editing components, routes, state, API clients, styles, configs, or tests, complete enough analysis and planning for the change to be reviewable. Scale the plan to risk: a simple low-risk single-component change can use a short inline plan; multi-file, API-visible, accessibility-sensitive, release, bug-fix, branch/MR, unclear-risk, or high-risk work needs explicit task split, acceptance checks, verification commands, rollback or stop conditions, and named handoffs to testing, miniapp/app, backend, or diagnosis skills before edits. Runtime-visible work additionally consumes the canonical UI/UX delivery contract's Design brief and Test selection Phase 0 before the first implementation edit.
Repo-local agent contracts (`AGENTS.md` at the repo root and in source directories) are part of the delivery contract: when a change moves a stable boundary, generated surface, workflow, or directory-local rule, update the nearest contract in the same MR and keep coverage in sync per `product-rd-workflow`'s spec / repo-contract sync gate.
When checking a React project against team standards, split findings into deterministic checks and agent review checks. Deterministic checks cover package scripts, typecheck/lint/test/E2E commands, generated API client usage, environment configuration, CI gates, bundle/performance budgets, and request/trace identifier propagation in central clients. Agent review checks cover component ownership, state placement, API contract alignment, finite-value mapping, accessibility/design quality, and whether tests assert behavior instead of only rendering. For the concrete deterministic executor list (ecosystem linter/analyzer rules — `eslint-plugin-react-hooks`, `@typescript-eslint` typed rules, `dependency-cruiser`, tsconfig `strict`/`noUncheckedIndexedAccess`) and the shipped client language-basics conformance checkers, see `testing-strategy/references/fitness-functions.md` §4.1.3 (client language-basics; spec 006). Prefer enabling ecosystem rules over hand-rolling checks.
1. Define the web surface.
- Route/page, component boundary, URL params/query state, auth/permission state, responsive breakpoints, and browser support.
- User-visible states: loading, skeleton, empty, partial, success, error, retry, disabled, permission denied, stale/offline, and optimistic update.
- Data boundary: API client, request cancellation, cache/revalidation, mutation invalidation, pagination, streaming/websocket if used, and typed error mapping.
- API observability: central clients should attach or preserve request/trace/operation identifiers, measure duration, distinguish cancel from failure, classify upload or long-running requests, and map backend envelopes into typed user-facing errors.
- Finite-value boundary: generated API enums, backend string codes, URL query values, route params, filters, analytics dimensions, and display labels should flow through one typed client/domain mapping module. Components should use the mapped symbols and label tables instead of scattering raw values such as `"US"`, `"CN"`, `"active"`, or `"default"` in render, tests, routing, or tracking code. If shared client-domain ownership is unclear, keep a local mapper for the slice, mark temporary duplicate/raw uses with `finite-value-debt: <task-ref> <owner> <deadline> <reason>`, and record the consolidation owner. Architecture owns the cross-stack semantic decision when the same value must align across web, app, mini-program, backend, storage, and analytics.
2. Analyze the existing web surface.
- Locate the owning route/page, component tree, state owner, API client, data-fetching layer, styling system, tests, and build scripts before editing.
- Identify whether state belongs in URL/query params, cache/server state, form state, local component state, browser storage, or global app state.
- Read repo wrappers first: package manager, dev/build scripts, lint/typecheck/test runners, browser/E2E tools, environment variables, and generated clients.
- Before generating component-library code: the **workspace lockfile resolution is the version authority** (`npm ls <pkg>` / `pnpm why` / yarn equivalent — a library config file or global CLI can resolve a different release than the workspace); take configuration ground truth (framework, aliases, installed components) from the library's own introspection surface (config file such as `components.json`, official info CLI/MCP, or the installed package's exports/types); write APIs against the resolved version, never from memory of "current" APIs (prop names and defaults shift across majors). After editing, close with the library's own linter/codemod check on the changed files when one exists (deprecated-usage and a11y rules the generic lint config does not know); for a library major-version migration, follow the official migration checklist + changelog for the exact from→to pair, apply, then re-run the library lint to prove no deprecated usage remains.
- If a design exists, map visible states and interactions to component ownership before implementing.
- For every visible UI change, load `../product-ui-ux-design/references/delivery-contract.md` and consume either its full Design brief + Phase 0 or its valid low-risk copy-only record + lightweight Phase 0 before coding. The lightweight path checks semantics, accessible name, localization, rendered extent, and target render without inventing unrelated matrices; risk-bearing copy uses the full path. For full slices, map structure, state/adaptation matrices, behavior and criteria to React ownership; record route/server, component/state owners, viewports/themes/input modes, and preserved behavior. When React is embedded in a native WebView, mini-program `web-view`, or Electron shell, this skill owns the content-layer member; the native/mini/desktop host owner must add its separate entry, binding and runtime record, even when host code is unchanged.
- Before the first implementation edit, add the canonical `client_entry` defined there: local rule identifier or short quote and implementation decision, target surface/runtime, planned run/capture command, and behavior that must remain unchanged.
3. Structure React code by ownership.
- Decompose UI by responsibility, not by arbitrary visual fragments.
- Put state at the lowest owner that needs to read/write it; lift only when siblings need shared state.
- Keep derived data derived during render or memoized only when measured or clearly necessary.
- Avoid Effects for pure derived state, event handling, or data transformations that can happen during render.
- Isolate side effects: network, subscriptions, timers, storage, analytics, and imperative browser APIs.
- Keep route loaders/actions, client caches, or data-fetching libraries aligned with the repo pattern.
4. Implement browser behavior deliberately.
- Forms need validation, submit pending state, disabled/retry behavior, server error mapping, and keyboard behavior.
- Navigation needs route guards, deep links, back/forward behavior, scroll/focus restoration, and not-found/permission states.
- Tables/lists need stable keys, empty/error rows, pagination or virtualization when needed, persisted filters where useful, selected-count state, bulk operation feedback, clear reload/reset behavior after actions, and non-janky loading.
- Workbench pages need explicit route/layout ownership, context strips, active job/task entries, permission-gated actions, and drawer/detail inspection that preserves parent context.
- Workbench layout needs code-level geometry: bounded shell/header/control/work regions, sticky or preserved context, named collapse rules, stable empty/loading/error geometry, and secondary panels that collapse before primary content becomes unreadable.
- Complex workbench variants are reference-level material, not entrypoint material. If the surface is a dense review, report, assignment, resource, assistant, media/capture, or app-hosted workspace, load `references/complex-workspace-patterns.md` and apply only the relevant pattern family.
- In complex workspaces, declare state owners for route/context, selection, filters, permissions, async jobs, restored preferences, media readiness, submit/finality, and child drawers/panels before coding. Validate restored state against the current route, identity, permission, task type, and available item count.
- Mature workspace shells should implement code-level contracts, not only CSS: token-to-theme binding, startup context, route/permission-derived navigation, durable jobs, measured overflow, secondary-panel collapse, upload/parse state machines, and browser screenshot acceptance at declared stress widths.
- Token provenance must be visible in code: map design tokens into the component-library theme first, then local CSS should reference theme variables or documented semantic values.
- Workbench shell responsiveness needs explicit code thresholds: minimum widths, fallback layout, scroll owner, sticky enablement, and collapse order.
- Embedded, hosted, or app-container web shells need code-level ownership for entry paths, host/source detection, allowlisted origins, defensive message parsing, layout switching, persisted host flags, normal-browser fallback, lifecycle restore, and storage failure recovery.
- Auth, account, assistant, report, assignment, resource, media/capture, and AI-recognition variants are detailed in `references/complex-workspace-patterns.md`; do not keep their source-specific state catalogs in this entrypoint.
- Long work, high-risk submits, destructive actions, and AI/data operations need pending/final state, duplicate-submit protection, timeout/failure UI, retry/recovery, and a stable visible identifier when support or reconciliation may be needed.
- Configurable shortcuts or command palettes need a parsed and normalized registry, platform-aware display labels, reserved/non-rebindable shortcut checks, duplicate and conflict warnings before lossy config parsing, explicit scope/context priority, user override plus explicit unbind semantics, invalid-config fallback to defaults, reload/delete cleanup, command action allowlists, and collision-safe discovery UI. Dispatch must isolate shortcuts from text inputs, editable fields, composition/IME, modal focus traps, and command palette focus; chords or multi-step sequences need timeout/cancel handling, propagation rules, and cleanup on unmount.
- Chart, canvas, image, PDF, annotation, dense table, card, menu, browser storage, and cross-tab behavior need lifecycle cleanup, measured overflow, accessibility, and browser evidence at realistic container widths.
5. Debug systematically when behavior is wrong.
- Reproduce with the smallest page, route, component test, browser trace, or network fixture that shows the failure.
- Classify the failure by layer: route, render/hydration, component state, effect/subscription, API contract, cache/revalidation, browser storage, permission/auth, build/env, or deployment/cache.
- Inspect console errors, failed network requests, request/response payloads, React warnings, route params, cache state, feature flags, and environment variables before changing code.
- Prove whether the issue is browser-only, data-contract, state ownership, styling/layout, or backend behavior; route backend fixes to backend skills.
- Add regression evidence at the lowest sufficient layer, then run browser smoke for visible flows.
6. Verify in a real browser.
- Run the repo's formatter, typecheck, lint, unit/component tests, and build or affected checks.
- When writing the test code itself (structure, naming, smells, fixtures, behavior-vs-state, coverage, isolation, parameterization), pick the matching § from the decision table in `testing-strategy/references/test-code-authoring-patterns.md`; enable the per-stack lint executors for its machine-decidable smells (conditional logic / sleep / assertion-free tests) per `testing-strategy/references/fitness-functions.md` §4.1.4 (Jest/Vitest/Playwright ESLint rules).
- **TC traceability**: link tests via the `createTcSuite(test, describe)` factory wrapper. Registers at collection time so `.skip` / `.skipIf` / `.todo` still map to Bitable status. Full overloads supported: `.concurrent` / `.each` / `(name, options, fn)` / `(name, fn, timeout)`. Helper from `test-artifact-management/references/tc_helpers/tc.ts`, installed under `test/tc.ts`. See `test-artifact-management/references/tc-marker-conventions.md`. Before adding tests, `grep -rn 'tcTest\|tcDescribe' src/ __tests__/` plus the sidecar `test/results/tc-map.jsonl` to check for existing coverage — extend rather than duplicate. When a TC is marked 废弃, grep both source and sidecar; follow deprecation cascade in `testing-strategy`. Tests without any TC link: prompt user only when the underlying code is also removed.
- **废弃级联:业务代码是否仍在用** — TS/JS 用 `madge` 拿依赖图最准,没安装则 grep 兜底:
1. `npx madge --dependents src/path/to/Module.tsx`(列出谁 import 了它);或 `grep -rEn "from ['\"][./]*<path>" src/`
2. 排除测试文件后还有 import → 产品代码在用,不删;只剩这个测试 → 同 commit 删模块 + 测试
3. 路由级别另查:`grep -rn "<RouteComponent>" src/router src/routes`;运行时 lazy import (`React.lazy(() => import('...'))`) madge 能抓但要 `--include-npm` 等参数核对
4. 边界:路径别名(`@/foo`)需 madge 的 `tsconfig` 配;动态 `import(name)` 字面值为变量时 grep 抓不到;CSS / 静态资源 import 的 dead-asset 由 build 报告
- For API-backed UI, test component states, API client parsing/error translation, and at least one browser/E2E smoke path when feasible.
- Inspect the rendered page in a browser for any visible UI change, responsive behavior, empty/error states, and console/network errors.
- For UI/UX redesign evidence, include the declared stress viewport, or when none exists use the minimum supported width plus one narrow stress width such as 320px; text wrapping/overflow; loading/empty/error/final states; keyboard/focus path; and a browser screenshot or equivalent visual artifact. Mark each dimension covered or `N/A` with a one-line reason; `N/A` is valid only when the reason names a verifiable structural fact, explains why that fact makes the dimension unreachable or unchanged for this slice, and includes a checkable pointer such as a file path, config key, or commit that resolves at review time. Persist evidence artifacts where reviewers can access them using sanitized/test accounts and redacting tokens, PII, credentials, private paths, and raw personal data; delete temporary smoke pages or helper scripts before commit unless the repo intentionally owns them.
- Return the complete canonical client-record member defined in `../product-ui-ux-design/references/delivery-contract.md` for testing Phase 1 and the design verdict. The member includes its applied rule/decision, affected files/components, preserved behavior, exact command, immutable candidate binding, producer member/version actually exercised, artifacts, tested route/server, viewport/container sizes, themes/input modes/states, criterion-mapped observations, console/network checks, coverage boundary, and gaps. The browser render proves only the captured content layer; it cannot close an embedded host or unbound producer member. `testing-strategy` records aggregate sufficiency before the design owner records the candidate-bound verdict.
- For browser-runtime changes, browser smoke is a completion gate when lower layers cannot prove the behavior. This includes changes to routing, browser storage/session restore, streaming/fetch finality, visibility or foreground/background behavior, permission/capability prompts, WebView bridge callbacks, upload/media flows, and rendered loading/error/final states. If the browser or app server is missing, first attempt normal setup; if still unavailable, stop at `pre-runtime-test-ready` or `blocked` and name the owner, attempted commands, residual risk, and next unblock action. `pre-runtime-test-ready` is handoff-only, not merge-ready, release-ready, or complete.
- Check accessibility names, labels, focus order, keyboard navigation, aria only when semantic HTML is insufficient, contrast, and text wrapping.
- Check performance when relevant: bundle impact, unnecessary renders, long lists, image loading, code splitting, hydration/runtime errors, and Core Web Vitals risk.
## Non-Negotiable Rules
- Do not use mocked happy-path component tests as proof that API integration works.
- Do not add Effects for state that can be derived from props/state during render.
- Do not ship user-visible UI without inspecting the rendered browser surface when layout or interaction changed.
- Do not add hidden keyboard traps, icon-only controls without accessible names, or mouse-only critical actions.
- Do not ship configurable shortcuts as scattered `keydown` handlers; centralize parsing, normalization, scope resolution, reserved-key enforcement, unbind/override behavior, and text-input or modal isolation.
- Do not let server transport errors leak directly into user copy; map them to useful UI states.
- Do not ship high-risk actions with only optimistic UI or generic success/error toasts; users must be able to tell whether the operation is pending, succeeded, failed, retryable, blocked, or needs support.
- Do not treat a frontend API client as done until empty response, invalid JSON, non-2xx envelope, auth expiry, network failure, cancellation, and backend error message extraction are covered at the client or component boundary when relevant.
- Do not scatter backend enum/string literals through React components, URL/query handling, analytics, or tests. Centralize finite-value parsing, display labels, defaults, and unknown-value behavior at the API/client-domain boundary, and keep raw literals only in clearly named boundary conversion tests that cover every known external value plus unknown/default behavior. Migrate existing non-boundary test raw literals for that value in the same pull request or mark each remaining use with `finite-value-debt: <task-ref> <owner> <deadline> <reason>`, even when the current slice does not introduce a new mapper.
- Do not debug React/browser failures from code inspection alone when a browser reproduction, console output, network trace, screenshot, or focused test can be collected.
- Do not claim a web client fix is complete without naming the browser/rendered verification that was run. If required browser/runtime verification is unavailable after remediation, the status is `pre-runtime-test-ready` or `blocked`, not complete.
## Reference Loading
- For source provenance, current extraction boundary, and keep/merge/discard decisions, read `references/source-evidence-map.md` when auditing or re-extracting this skill.
- For embedded H5 inside a host (mini-program `web-view` / native WebView / payment / vendor app WebView) — H5-author POV: env detection, bridge abstraction, auth-from-host (cookieless), hardware-back integration, safe-area + viewport-fit, host capability degradation, WeChat JSSDK specifics, offline / lifecycle, cross-app navigation, anti-patterns, multi-host smoke matrix — read `references/embedded-h5-in-host.md`. The host-side contract (web-view component / WebView shell config / native bridge setup) is owned by `miniapp-product-dev` (mini-program host) and `app-cross-platform-dev` (native WebView shell).
- For joint extraction from Figma design source AND a React/web monorepo (with package class mapping, design-token cross-validation, deprecation-marker detection), read `../skill-extraction-workflow/references/two-source-extraction-pattern.md`. Use when both sources are available; produces aligned design + implementation rules with cross-source token validation.
- For component decomposition, state ownership, effects, routing, forms, and data fetching, read `references/react-architecture.md`.
- For dense review, report, assignment, resource, assistant, media/capture, or app-hosted workspace state-machine patterns, read `references/complex-workspace-patterns.md`.
- For browser accessibility, keyboard/focus, responsive behavior, and visual verification, read `references/web-ui-quality.md`.
- For API integration, caching, error handling, testing, performance, build, and deployment readiness, read `references/web-quality-release.md`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!