| name | react-conventions |
| description | Use this skill whenever you are about to create, modify, or refactor React code in this project's `frontend/` directory — including components (.tsx files under `components/` or `views/`, plus `App.tsx`), custom hooks (.ts files under `hooks/`), or any file that imports from `react`. Enforces the project's React rules: the 50-line component limit, functional components only, `useMemo`/`useCallback` for expensive computations, and the `use` prefix for custom hooks. Trigger on any task that involves writing JSX/TSX in this repo, even when the user does not name a specific rule — phrases like "build a component", "add a view", "create a hook", "wire up this page", "refactor this React code", "fix this re-render", or "split this component" should all invoke this skill. |
React Conventions
This skill is the operational layer for the project's React style rules. The authoritative rule text lives in .claude/rules/react.md, .claude/rules/code-standards.md, and .claude/rules/folder-structure.md — this skill turns those rules into a concrete workflow you can follow while writing or modifying any .tsx / hook file under frontend/src/.
Why an operational skill on top of the rules? Because reading a rule is not the same as applying it. The checklist below is what catches the easy slips — a 60-line component that "felt" small, a helper named fetchUser that secretly uses useState, a useMemo wrapped around a string literal, a page component dropped into components/ instead of views/.
Before you write any React code
- Re-skim the rules: open
.claude/rules/react.md and .claude/rules/folder-structure.md. Conventions drift; never assume your memory of them is current.
- Look at a sibling: open one or two existing files in the target folder (
frontend/src/components/, frontend/src/views/, frontend/src/hooks/) and match their shape — imports order, prop typing style, how data is fetched, how loading/empty states are handled. Your file should look like it belongs next to those.
- Pick the right home up front using the placement table below. Putting a file in the wrong folder is the most expensive kind of mistake to undo later because it leaks into import paths everywhere.
File placement quick-reference
| What you're writing | Goes in | Example file name |
|---|
| Page component (mapped to a route) | src/views/ | LoginView.tsx |
| Reusable UI component | src/components/ | ProductCard.tsx |
| shadcn/ui primitive | src/components/ui/ | button.tsx |
Custom hook (useXxx) | src/hooks/ | useUser.ts |
| API client to the backend | src/services/ | userService.ts |
| Pure helper / formatter | src/lib/ | formatCurrency.ts |
| Type / interface / DTO | src/types/ | User.ts |
| Context provider + its hook | src/contexts/ | AuthContext.tsx |
One type/class per file. One hook per file. One component per file (small private subcomponents are fine when they only serve the file's main export).
The four React rules in practice
Rule 1 — Components ≤ 50 lines
Count lines as you write. If a component is heading past 30-40 lines, stop and split before finishing — fixing it after the fact is much harder because the pieces have already grown tangled.
Three ways to split, roughly in this order of preference:
- Extract subcomponents for visually distinct sections (header, list, sidebar, footer, item row).
- Extract a custom hook for data fetching, derived state, or any stateful logic that is independent of the JSX.
- Extract pure helpers to
src/lib/ for formatting, parsing, or computation that doesn't touch React at all.
A component's job is to compose. Fetching, computing, and assembling JSX should not all live in the same function body.
Rule 2 — Functional components only
Always export function ComponentName(props) {}. Never class X extends Component. Use hooks for everything:
useState for local state
useEffect for side effects
useRef for refs or mutable values that shouldn't trigger re-renders
useContext for context
- Custom
useXxx hooks for any reusable stateful logic
If you find a class component while refactoring, convert it — don't leave it.
Rule 3 — Memoize what matters, not everything
useMemo and useCallback are tools for two specific situations:
- The computation is non-trivial (sorting, filtering, reducing over arrays; deriving a complex object).
- The value is a dependency that needs a stable reference — a
useEffect / useMemo dependency array, a React.memo child's prop, or a prop passed into a memoized hook.
Do not wrap primitives, cheap string concatenations, or values that flow only into plain DOM elements. Over-memoization adds noise without speed and can actually hurt performance by keeping closures alive.
When you do memoize, the dependency array must be exhaustive — every value referenced inside the callback must appear in the deps.
Rule 4 — Custom hooks start with use
Any function that calls another hook is itself a hook. That's not a style preference — it's a rule of hooks enforced by React itself and the linter.
- Name it
useSomething in camelCase.
- Place it in
src/hooks/, one hook per file.
- If you catch yourself writing
useState or useEffect inside a function that doesn't start with use, rename and move it before continuing.
The general code standards still apply
The React rules complement .claude/rules/code-standards.md. The standards that bite most often in React code:
- English-only identifiers — no
usuario, pedidos, valorTotal.
- No magic numbers —
const PAGE_SIZE = 20; not items.slice(0, 20).
- At most 2 levels of
if/else nesting — prefer early returns and guard clauses (if (!user) return null;).
- No
switch/case — use a record/map lookup instead.
- No inline comments in function bodies — extract a well-named helper or rename a variable instead.
- At most 3 parameters — beyond that, accept a single options object.
- Files ≤ 100 lines — same split-by-responsibility logic as components.
Tests
Any non-trivial hook or component should have tests under the same conventions as the rest of the project (.claude/rules/tests.md):
- Unit tests for hooks (Vitest + React Testing Library), structured GIVEN / WHEN / THEN.
- Integration tests for views that compose real services.
- E2E (Playwright) only for critical user journeys — don't duplicate unit coverage.
If you're modifying a file that already has a test, update the test in the same change.
Self-review checklist
Run this mentally before declaring a React change done. Each item maps to a rule above — if you can't tick one, fix it before handing back.