React — Checklists¶
OWNER: floris, floor ALSO_USED_BY: alexander, tobias LAST_VERIFIED: 2026-03-26 GE_STACK_VERSION: React 19.x
Overview¶
Machine-parseable checklists for component quality, accessibility, and performance. Run through these before marking a component as complete.
COMPONENT QUALITY CHECKLIST (every component)¶
- [ ] CHECK: component has explicit TypeScript return type
- [ ] CHECK: props interface is exported and named
{Component}Props - [ ] CHECK: no
anytypes —unknownwith type guards instead - [ ] CHECK: named export only — no default exports
- [ ] CHECK: file is under 200 lines IF_SKIPPED: component becomes unmaintainable, extract hooks/sub-components
- [ ] CHECK: one exported component per file
- [ ] CHECK: no "use client" unless component uses hooks or event handlers IF_SKIPPED: entire subtree becomes client-rendered unnecessarily
- [ ] CHECK: "use client" is at the smallest leaf, not a layout or page
- [ ] CHECK: co-located test file exists (
component-name.test.tsx) - [ ] CHECK: no inline style objects — Tailwind classes only
- [ ] CHECK: conditional classes use
cn()utility - [ ] CHECK: shadcn/ui used when a matching primitive exists
ACCESSIBILITY CHECKLIST (every interactive component)¶
- [ ] CHECK: all form inputs have associated
<label>elements IF_SKIPPED: screen readers cannot identify the input - [ ] CHECK: error messages use
role="alert" - [ ] CHECK: interactive elements are keyboard accessible (Tab, Enter, Escape)
- [ ] CHECK: images have
alttext (emptyalt=""for decorative images) - [ ] CHECK: buttons have visible text or
aria-label - [ ] CHECK:
aria-invalidis set on inputs with validation errors - [ ] CHECK: modals trap focus and return focus on close
- [ ] CHECK: color is not the only indicator of state (add icon or text)
- [ ] CHECK: heading hierarchy is logical (no skipping levels)
- [ ] CHECK: custom components use appropriate ARIA roles IF_SKIPPED: assistive technology cannot interpret the component
PERFORMANCE CHECKLIST (components rendering lists or heavy data)¶
- [ ] CHECK: lists with 50+ items use virtualization (tanstack-virtual or similar) IF_SKIPPED: renders all DOM nodes — sluggish on mobile
- [ ] CHECK: no manual useMemo/useCallback if React Compiler is active
- [ ] CHECK: images use Next.js
<Image>with width/height or fill - [ ] CHECK: heavy components are lazy-loaded with
React.lazy+ Suspense - [ ] CHECK: no useEffect for data fetching — TanStack Query instead IF_SKIPPED: no caching, no dedup, race conditions
- [ ] CHECK: key prop uses stable unique ID, not array index IF_SKIPPED: reorder/delete corrupts component state
- [ ] CHECK: context values are memoized to prevent cascade re-renders
- [ ] CHECK: derived state is computed during render, not synced via useEffect IF_SKIPPED: unnecessary extra render cycle
- [ ] CHECK: no inline object/function props to memoized children IF_SKIPPED: memo is bypassed on every render
FORM CHECKLIST (every form component)¶
- [ ] CHECK: uses React Hook Form with zodResolver
- [ ] CHECK: Zod schema is shared between client and Server Action
- [ ] CHECK: Server Action uses
safeParse, notparse - [ ] CHECK: validation mode is
onBlur - [ ] CHECK: submit button disabled during submission
- [ ] CHECK: field errors render below the field with
role="alert" - [ ] CHECK: server errors (non-field) render at the top of the form
- [ ] CHECK: uses
.issuesnot.errorson ZodError (Zod v4) IF_SKIPPED: error display silently breaks ADDED_FROM: ge-admin-ui-2026-02, Zod v4 migration
Cross-References¶
READ_ALSO: wiki/docs/stack/react/index.md READ_ALSO: wiki/docs/stack/react/pitfalls.md READ_ALSO: wiki/docs/stack/react/forms.md READ_ALSO: wiki/docs/stack/react/patterns.md