#1

React Review Audit

Openreact-doctor[bot]opened 6mo ago

Score: 87/100 · 1 error · 33 warnings

Copy as prompt
Fix the following React Review diagnostics in my codebase.

## Errors (1)

1. [error] effect-needs-cleanup — src/app/chat/[roomId]/page.tsx:187
   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 (33)

2. [warning] async-await-in-loop — src/lib/db.ts:52
   await inside a while-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

3. [warning] async-await-in-loop — src/lib/db.ts:66
   await inside a while-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

4. [warning] design-no-three-period-ellipsis — src/components/StatusBanner.tsx:38
   Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

5. [warning] design-no-three-period-ellipsis — src/components/StatusBanner.tsx:56
   Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

6. [warning] no-generic-handler-names — src/components/GitHubStars.tsx:26
   Non-descriptive handler name "handleClick" — name should describe what it does, not when it runs

7. [warning] no-cascading-set-state — src/hooks/useSocket.ts:45
   46 setState calls in a single useEffect — consider using useReducer or deriving state

8. [warning] no-autofocus — src/components/GifPicker.tsx:132
   The `autoFocus` attribute is found here, which can cause usability issues for sighted and non-sighted users.

9. [warning] nextjs-no-img-element — src/components/GifPicker.tsx:171
   Use next/image instead of <img> — provides automatic optimization, lazy loading, and responsive srcset

10. [warning] async-await-in-loop — src/hooks/useMessages.ts:165
   await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

11. [warning] no-autofocus — src/app/chat/[roomId]/page.tsx:320
   The `autoFocus` attribute is found here, which can cause usability issues for sighted and non-sighted users.

12. [warning] nextjs-missing-metadata — src/app/chat/[roomId]/page.tsx:1
   Page without metadata or generateMetadata export — hurts SEO

13. [warning] rerender-state-only-in-handlers — src/app/chat/[roomId]/page.tsx:79
   useState "joined" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

14. [warning] no-giant-component — src/app/chat/[roomId]/page.tsx:73
   Component "ChatPage" is 354 lines — consider breaking it into smaller focused components

15. [warning] nextjs-no-client-side-redirect — src/app/chat/[roomId]/page.tsx:192
   router.push() in useEffect — use redirect() from next/navigation or handle navigation in an event handler

16. [warning] react-compiler-destructure-method — src/app/chat/[roomId]/page.tsx:192
   Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

17. [warning] react-compiler-destructure-method — src/app/chat/[roomId]/page.tsx:213
   Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

18. [warning] react-compiler-destructure-method — src/app/chat/[roomId]/page.tsx:254
   Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

19. [warning] design-no-redundant-padding-axes — src/app/chat/[roomId]/page.tsx:397
   px-4 py-4 → use the shorthand p-4

20. [warning] rerender-state-only-in-handlers — src/components/ChatInput.tsx:35
   useState "recording" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

21. [warning] no-generic-handler-names — src/components/ChatInput.tsx:200
   Non-descriptive handler name "handleChange" — name should describe what it does, not when it runs

22. [warning] js-index-maps — server/roomManager.ts:106
   array.findIndex() in a loop is O(n*m) — build a Map for O(1) lookups

23. [warning] nextjs-no-img-element — src/components/ChatBubble.tsx:40
   Use next/image instead of <img> — provides automatic optimization, lazy loading, and responsive srcset

24. [warning] nextjs-no-img-element — src/components/ChatBubble.tsx:50
   Use next/image instead of <img> — provides automatic optimization, lazy loading, and responsive srcset

25. [warning] no-inline-bounce-easing — src/components/TypingIndicator.tsx:7
   animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration

26. [warning] no-inline-bounce-easing — src/components/TypingIndicator.tsx:11
   animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration

27. [warning] no-inline-bounce-easing — src/components/TypingIndicator.tsx:15
   animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration

28. [warning] no-unknown-property — src/components/Antigravity.tsx:219
   Unknown property found

29. [warning] no-unknown-property — src/components/Antigravity.tsx:221
   Unknown property found

30. [warning] no-unknown-property — src/components/Antigravity.tsx:224
   Unknown property found

31. [warning] no-unknown-property — src/components/Antigravity.tsx:226
   Unknown property found

32. [warning] no-unknown-property — src/components/Antigravity.tsx:228
   Unknown property found

33. [warning] nextjs-missing-metadata — src/app/page.tsx:1
   Page without metadata or generateMetadata export — hurts SEO

34. [warning] react-compiler-destructure-method — src/app/page.tsx:25
   Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

❌ 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 () =&gt; target.removeEventListener(name, handler) for listeners, return () =&gt; clearInterval(id) / clearTimeout(id) for timers, or return unsubscribe if the subscribe call already returned one

src/app/chat/[roomId]/page.tsx:187


⚠️ Warnings (33)

no-unknown-property

Unknown property found

Remove unknown property

src/components/Antigravity.tsx:219
src/components/Antigravity.tsx:221
src/components/Antigravity.tsx:224
src/components/Antigravity.tsx:226
src/components/Antigravity.tsx:228

react-compiler-destructure-method

Destructure for clarity: const { push } = useRouter() then call push(...) directly — easier for React Compiler to memoize and clearer about which methods this component depends on

Destructure the method up front: const { push } = useRouter() then call push(...) directly — clearer dependency graph and easier for React Compiler to memoize

src/app/chat/[roomId]/page.tsx:192
src/app/chat/[roomId]/page.tsx:213
src/app/chat/[roomId]/page.tsx:254
src/app/page.tsx:25

async-await-in-loop

await inside a while-loop runs the calls sequentially — for independent operations, collect them and use await Promise.all(items.map(...)) to run them concurrently

Collect the items and use await Promise.all(items.map(...)) to run independent operations concurrently

src/lib/db.ts:52
src/lib/db.ts:66
src/hooks/useMessages.ts:165

nextjs-no-img-element

Use next/image instead of <img> — provides automatic optimization, lazy loading, and responsive srcset

import Image from 'next/image' — provides automatic WebP/AVIF, lazy loading, and responsive srcset

src/components/GifPicker.tsx:171
src/components/ChatBubble.tsx:40
src/components/ChatBubble.tsx:50

no-inline-bounce-easing

animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration

Use cubic-bezier(0.16, 1, 0.3, 1) (ease-out-expo) for natural deceleration — objects in the real world don't bounce

src/components/TypingIndicator.tsx:7
src/components/TypingIndicator.tsx:11
src/components/TypingIndicator.tsx:15

design-no-three-period-ellipsis

Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or &hellip;)

Use the typographic ellipsis "…" (or &hellip;) instead of three periods — pairs with action-with-followup labels ("Rename…", "Loading…")

src/components/StatusBanner.tsx:38
src/components/StatusBanner.tsx:56

no-generic-handler-names

Non-descriptive handler name "handleClick" — name should describe what it does, not when it runs

Rename to describe the action: e.g. handleSubmit → saveUserProfile, handleClick → toggleSidebar

src/components/GitHubStars.tsx:26
src/components/ChatInput.tsx:200

no-autofocus

The autoFocus attribute is found here, which can cause usability issues for sighted and non-sighted users.

Remove the autoFocus attribute.

src/components/GifPicker.tsx:132
src/app/chat/[roomId]/page.tsx:320

nextjs-missing-metadata

Page without metadata or generateMetadata export — hurts SEO

Add export const metadata = { title: '...', description: '...' } or export async function generateMetadata()

src/app/chat/[roomId]/page.tsx:1
src/app/page.tsx:1

rerender-state-only-in-handlers

useState "joined" 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

src/app/chat/[roomId]/page.tsx:79
src/components/ChatInput.tsx:35

no-cascading-set-state

46 setState calls in a single useEffect — consider using useReducer or deriving state

Combine into useReducer: const [state, dispatch] = useReducer(reducer, initialState)

src/hooks/useSocket.ts:45

no-giant-component

Component "ChatPage" is 354 lines — consider breaking it into smaller focused components

Extract logical sections into focused components: &lt;UserHeader /&gt;, &lt;UserActions /&gt;, etc.

src/app/chat/[roomId]/page.tsx:73

nextjs-no-client-side-redirect

router.push() in useEffect — use redirect() from next/navigation or handle navigation in an event handler

Avoid redirects inside useEffect. Use an event handler, middleware, or server-side redirect (App Router: redirect() from next/navigation; Pages Router: getServerSideProps redirect)

src/app/chat/[roomId]/page.tsx:192

design-no-redundant-padding-axes

px-4 py-4 → use the shorthand p-4

Collapse px-N py-N to p-N when both axes match. Keep them split only when one axis varies at a breakpoint (py-2 md:py-3)

src/app/chat/[roomId]/page.tsx:397

js-index-maps

array.findIndex() in a loop is O(n*m) — build a Map for O(1) lookups

Build an index Map once outside the loop instead of array.find(...) inside it

server/roomManager.ts:106


Last scored May 14, 2026 at 7:35 AM UTC. Maintained by React Review.

Activity

0

No activity yet.