React component rules
Standing rules for React code an assistant writes, covering function components, the rules of hooks, colocated state, stable list keys, accessible markup and no effect-driven derived state.
When you write or change React components in this project:
Components
- Write function components with hooks. Do not add class components.
- Give each component one responsibility. Split it when it mixes data loading, state logic and layout, or grows hard to read in one screen.
- Never define a component inside another component's body; it remounts on every render and loses its state.
- Type props explicitly in TypeScript files. Do not spread unknown props onto DOM elements.
- Follow the project's existing patterns for styling, file naming, exports and data fetching.
Hooks
- Call hooks only at the top level of components and custom hooks, never inside conditions, loops or callbacks. Name custom hooks
useSomething. - Satisfy the exhaustive-deps lint rule by fixing the dependencies, not by disabling the rule.
State
- Keep state as close as possible to where it is used, and lift it only when siblings must share it.
- Store the minimum. Compute anything derivable from props or state during render, and do not copy props into state (unless the prop is only an initial value, named like
initialCount). - Reset a component's state by changing its
key, not with an effect. - Use context for values that change rarely (theme, current user, locale), not for fast-changing state.
- Never mutate state or props. Create new objects and arrays.
Effects
- Use
useEffectonly to synchronise with something outside React: subscriptions, timers, imperative DOM or third-party widgets. - Never use an effect to compute derived state or to react to an event. Put event logic in the event handler.
- Clean up every subscription, listener and timer in the effect's cleanup function.
- Fetch data with the project's data layer (framework loaders or a query library). If you must fetch in an effect, cancel stale requests with an
AbortControlleror an ignore flag.
Lists
- Give list items a stable, unique
keyfrom the data, such as an id. Never useMath.random(), and use the array index only for static lists that are never reordered, filtered or inserted into.
Accessibility
- Use semantic elements:
buttonfor actions,awithhreffor navigation, headings in order, lists for lists. - Never attach
onClickto adivorspanfor an action; use abutton. - Every form control has an associated label, every meaningful image has
alttext (decorative images getalt=""), and icon-only buttons have an accessible name. - Custom widgets must be operable by keyboard, with visible focus. Dialogs move focus in and return it when closed.
- Add ARIA attributes only when no native element provides the semantics.
Performance and safety
- Do not wrap everything in
useMemo,useCallbackormemo. Use them when profiling shows a cost, or when a stable reference is needed by a memoised child or an effect dependency. If the project uses the React Compiler, do not add manual memoisation at all unless the compiler skips that component. - Never pass untrusted content to
dangerouslySetInnerHTML. Sanitise it, or render it as text.
details
- kind
- Rule: standing instructions for everything the assistant does
- domain
- Software engineering
- category
- Conventions
- made for
- Frontend engineer, Full-stack engineer, Software engineer
- risk
- read-only
- version
- v1.0.0 · experimental
- reviewed
- 2026-10-02
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md, ChatGPT, claude.ai
use in
npx @hermes-hq/hodios install react-component-rules --target claude-codenpx skills add hermes-hq/hodios-dist --skill react-component-rules -a claude-codeRules are always-on instructions, so they are not in the plugins: add the skill, or paste the text into CLAUDE.md.
pairs well with
All of ConventionsTest-writing rules
Standing rules for tests an assistant writes, covering behaviour over implementation, no sleeps, deterministic data, mocks only at boundaries and one reason to fail per test.
test-writing-rulesHTTP API design rules
Rules for HTTP APIs covering resource naming, status codes, problem+json errors, cursor pagination, idempotency keys and versioning. Load when designing or changing HTTP endpoints.
api-design-rulesC# style rules
Standing rules for C# an assistant writes, covering nullable reference types, async all the way with cancellation tokens, records and pattern matching, dependency injection and xUnit tests.
csharp-style-rulesGo style rules
Standing rules for Go an assistant writes, covering wrapped errors, context propagation, small consumer-side interfaces, table-driven tests and no goroutines without an owner.
go-style-rulesJava style rules
Standing rules for Java an assistant writes, covering modern language features, immutability, Optional and null handling, exceptions, restrained streams, records and JUnit 5 tests.
java-style-rulesPython style rules
Standing rules for Python an assistant writes, covering type hints, pathlib, logging over print, explicit exceptions, safe subprocess calls, project layout and the project's own tooling.
python-style-rules