Score: 90/100 · 1 error · 25 warnings
Copy as prompt
Fix the following React Review diagnostics in my codebase.
## Errors (1)
1. [error] effect-needs-cleanup — hooks/use-wizard-game.ts:73
useEffect schedules `setTimeout(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls clearTimeout(...)
## Warnings (25)
2. [warning] label-has-associated-control — components/game/setup-screen.tsx:31
A form label must be associated with a control.
3. [warning] label-has-associated-control — components/game/setup-screen.tsx:55
A form label must be associated with a control.
4. [warning] label-has-associated-control — components/game/setup-screen.tsx:68
A form label must be associated with a control.
5. [warning] design-no-bold-heading — components/game/setup-screen.tsx:22
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
6. [warning] no-array-index-as-key — components/game/setup-screen.tsx:74
Array index "i" used as key — causes bugs when list is reordered or filtered
7. [warning] design-no-bold-heading — components/game/mode-select.tsx:14
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
8. [warning] label-has-associated-control — components/game/lobby-screen.tsx:60
A form label must be associated with a control.
9. [warning] label-has-associated-control — components/game/lobby-screen.tsx:75
A form label must be associated with a control.
10. [warning] label-has-associated-control — components/game/lobby-screen.tsx:112
A form label must be associated with a control.
11. [warning] design-no-bold-heading — components/game/lobby-screen.tsx:30
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
12. [warning] design-no-bold-heading — components/game/lobby-screen.tsx:169
font-bold on <h2> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
13. [warning] no-array-index-as-key — components/game/lobby-screen.tsx:229
Array index "i" used as key — causes bugs when list is reordered or filtered
14. [warning] design-no-three-period-ellipsis — components/game/lobby-screen.tsx:235
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
15. [warning] design-no-three-period-ellipsis — components/game/lobby-screen.tsx:260
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
16. [warning] design-no-bold-heading — components/game/round-result-overlay.tsx:20
font-bold on <h2> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
17. [warning] js-tosorted-immutable — lib/wizard/ai.ts:69
[...array].sort() — use array.toSorted() for immutable sorting (ES2023)
18. [warning] js-cache-property-access — lib/wizard/ai.ts:170
play.card.rank is read 4 times inside this loop — hoist into a const at the top of the loop body
19. [warning] rerender-lazy-state-init — hooks/use-multiplayer-game.ts:30
useState(createInitialState()) calls initializer on every render — use useState(() => createInitialState()) for lazy initialization
20. [warning] no-cascading-set-state — hooks/use-multiplayer-game.ts:361
4 setState calls in a single useEffect — consider using useReducer or deriving state
21. [warning] design-no-bold-heading — components/game/game-over-screen.tsx:19
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
22. [warning] no-static-element-interactions — components/game/card.tsx:60
Static HTML elements with event handlers require a role.
23. [warning] no-static-element-interactions — components/game/card.tsx:115
Static HTML elements with event handlers require a role.
24. [warning] no-cascading-set-state — hooks/use-wizard-game.ts:73
9 setState calls in a single useEffect — consider using useReducer or deriving state
25. [warning] nextjs-missing-metadata — app/page.tsx:1
Page without metadata or generateMetadata export — hurts SEO
26. [warning] rerender-state-only-in-handlers — app/page.tsx:34
useState "mode" is updated but never read in the component's return — use useRef so updates don't trigger re-renders❌ Errors (1)
effect-needs-cleanup
useEffect schedules setTimeout(...) but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls clearTimeout(...)
Return a cleanup function that releases the subscription / timer:
return () => target.removeEventListener(name, handler)for listeners,return () => clearInterval(id)/clearTimeout(id)for timers, orreturn unsubscribeif the subscribe call already returned one
⚠️ Warnings (25)
label-has-associated-control
A form label must be associated with a control.
Either give the label a
htmlForattribute with the id of the associated control, or wrap the label around the control.
components/game/setup-screen.tsx:31
components/game/setup-screen.tsx:55
components/game/setup-screen.tsx:68
components/game/lobby-screen.tsx:60
components/game/lobby-screen.tsx:75
components/game/lobby-screen.tsx:112
design-no-bold-heading
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
Use
font-semibold(600) orfont-medium(500) on headings — 700+ crushes letter counter shapes at display sizes
components/game/setup-screen.tsx:22
components/game/mode-select.tsx:14
components/game/lobby-screen.tsx:30
components/game/lobby-screen.tsx:169
components/game/round-result-overlay.tsx:20
components/game/game-over-screen.tsx:19
no-array-index-as-key
Array index "i" used as key — causes bugs when list is reordered or filtered
Use a stable unique identifier:
key={item.id}orkey={item.slug}— index keys break on reorder/filter
components/game/setup-screen.tsx:74
components/game/lobby-screen.tsx:229
design-no-three-period-ellipsis
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or …)
Use the typographic ellipsis "…" (or
…) instead of three periods — pairs with action-with-followup labels ("Rename…", "Loading…")
components/game/lobby-screen.tsx:235
components/game/lobby-screen.tsx:260
no-cascading-set-state
4 setState calls in a single useEffect — consider using useReducer or deriving state
Combine into useReducer:
const [state, dispatch] = useReducer(reducer, initialState)
hooks/use-multiplayer-game.ts:361
hooks/use-wizard-game.ts:73
no-static-element-interactions
Static HTML elements with event handlers require a role.
Add a role attribute to this element, or use a semantic HTML element instead.
components/game/card.tsx:60
components/game/card.tsx:115
js-tosorted-immutable
[...array].sort() — use array.toSorted() for immutable sorting (ES2023)
Use
array.toSorted()(ES2023) instead of[...array].sort()for immutable sorting without the spread allocation
js-cache-property-access
play.card.rank is read 4 times inside this loop — hoist into a const at the top of the loop body
Hoist the deep member access into a const at the top of the loop body:
const { x, y } = obj.deeply.nested
rerender-lazy-state-init
useState(createInitialState()) calls initializer on every render — use useState(() => createInitialState()) for lazy initialization
Wrap in an arrow function so it only runs once:
useState(() => expensiveComputation())
hooks/use-multiplayer-game.ts:30
nextjs-missing-metadata
Page without metadata or generateMetadata export — hurts SEO
Add
export const metadata = { title: '...', description: '...' }orexport async function generateMetadata()
rerender-state-only-in-handlers
useState "mode" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
Replace useState with useRef when the value is only mutated and never read in render —
ref.current = ...updates without re-rendering the component
Last scored May 14, 2026 at 7:35 AM UTC. Maintained by React Review.
Activity
0No activity yet.