#1

React Review Audit

Openreact-doctor[bot]opened 6mo ago

Score: 87/100 · 0 errors · 52 warnings

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

## Warnings (52)

1. [warning] nextjs-no-client-side-redirect — components/SearchInput.tsx:26
   router.push() in useEffect — use redirect() from next/navigation or handle navigation in an event handler

2. [warning] react-compiler-destructure-method — components/SearchInput.tsx:26
   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

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

4. [warning] nextjs-image-missing-sizes — app/liked/page.tsx:36
   next/image with fill but no sizes — the browser downloads the largest image. Add a sizes attribute for responsive behavior

5. [warning] design-no-bold-heading — app/liked/page.tsx:48
   font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)

6. [warning] click-events-have-key-events — components/PlayerContent.tsx:120
   Enforce a clickable non-interactive element has at least one keyboard event listener.

7. [warning] click-events-have-key-events — components/PlayerContent.tsx:160
   Enforce a clickable non-interactive element has at least one keyboard event listener.

8. [warning] no-static-element-interactions — components/PlayerContent.tsx:120
   Static HTML elements with event handlers require a role.

9. [warning] no-static-element-interactions — components/PlayerContent.tsx:160
   Static HTML elements with event handlers require a role.

10. [warning] design-no-redundant-size-axes — components/PlayerContent.tsx:122
   w-10 h-10 → use the shorthand size-10 (Tailwind v3.4+)

11. [warning] design-no-redundant-size-axes — components/PlayerContent.tsx:162
   w-10 h-10 → use the shorthand size-10 (Tailwind v3.4+)

12. [warning] no-pure-black-background — components/Player.tsx:20
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

13. [warning] nextjs-no-client-side-redirect — app/liked/components/LikedContent.tsx:26
   router.replace() in useEffect — use redirect() from next/navigation or handle navigation in an event handler

14. [warning] react-compiler-destructure-method — app/liked/components/LikedContent.tsx:26
   Destructure for clarity: `const { replace } = useRouter()` then call `replace(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

15. [warning] design-no-redundant-size-axes — components/Modal.tsx:77
   w-[25px] h-[25px] → use the shorthand size-[25px] (Tailwind v3.4+)

16. [warning] no-react19-deprecated-apis — hooks/useUser.tsx:1
   useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`

17. [warning] no-cascading-set-state — hooks/useUser.tsx:46
   6 setState calls in a single useEffect — consider using useReducer or deriving state

18. [warning] server-sequential-independent-await — app/layout.tsx:29
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

19. [warning] click-events-have-key-events — components/MediaItem.tsx:30
   Enforce a clickable non-interactive element has at least one keyboard event listener.

20. [warning] no-static-element-interactions — components/MediaItem.tsx:30
   Static HTML elements with event handlers require a role.

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

22. [warning] nextjs-image-missing-sizes — components/MediaItem.tsx:52
   next/image with fill but no sizes — the browser downloads the largest image. Add a sizes attribute for responsive behavior

23. [warning] rerender-state-only-in-handlers — providers/ModalProvider.tsx:16
   useState "isMounted" is updated but never read in the component's return — use useRef so updates don't trigger re-renders

24. [warning] rendering-hydration-no-flicker — providers/ModalProvider.tsx:18
   useEffect(setState, []) on mount causes a flash — consider useSyncExternalStore or suppressHydrationWarning

25. [warning] react-compiler-destructure-method — components/ListItem.tsx:30
   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

26. [warning] nextjs-image-missing-sizes — components/ListItem.tsx:52
   next/image with fill but no sizes — the browser downloads the largest image. Add a sizes attribute for responsive behavior

27. [warning] react-compiler-destructure-method — components/LikeButton.tsx:84
   Destructure for clarity: `const { refresh } = useRouter()` then call `refresh(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

28. [warning] no-react19-deprecated-apis — components/Input.tsx:1
   forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

29. [warning] react-compiler-destructure-method — components/Header.tsx:37
   Destructure for clarity: `const { refresh } = useRouter()` then call `refresh(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

30. [warning] no-pure-black-background — components/Header.tsx:56
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

31. [warning] react-compiler-destructure-method — components/Header.tsx:57
   Destructure for clarity: `const { back } = useRouter()` then call `back(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

32. [warning] no-pure-black-background — components/Header.tsx:71
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

33. [warning] react-compiler-destructure-method — components/Header.tsx:72
   Destructure for clarity: `const { forward } = useRouter()` then call `forward(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

34. [warning] react-compiler-destructure-method — components/Header.tsx:89
   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

35. [warning] react-compiler-destructure-method — components/Header.tsx:105
   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

36. [warning] react-compiler-destructure-method — components/Header.tsx:131
   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

37. [warning] no-react19-deprecated-apis — components/Button.tsx:1
   forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

38. [warning] rendering-usetransition-loading — hooks/useGetSongById.ts:8
   useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead

39. [warning] no-cascading-set-state — hooks/useGetSongById.ts:12
   4 setState calls in a single useEffect — consider using useReducer or deriving state

40. [warning] nextjs-no-client-side-redirect — app/account/components/AccountContent.tsx:18
   router.replace() in useEffect — use redirect() from next/navigation or handle navigation in an event handler

41. [warning] react-compiler-destructure-method — app/account/components/AccountContent.tsx:18
   Destructure for clarity: `const { replace } = useRouter()` then call `replace(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

42. [warning] rendering-usetransition-loading — components/UploadModal.tsx:18
   useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead

43. [warning] react-compiler-destructure-method — components/UploadModal.tsx:109
   Destructure for clarity: `const { refresh } = useRouter()` then call `refresh(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on

44. [warning] no-effect-event-handler — components/AuthModal.tsx:23
   useEffect simulating an event handler — move logic to an actual event handler instead

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

46. [warning] nextjs-missing-metadata — app/(site)/page.tsx:1
   Page without metadata or generateMetadata export — hurts SEO

47. [warning] click-events-have-key-events — components/SongItem.tsx:22
   Enforce a clickable non-interactive element has at least one keyboard event listener.

48. [warning] no-static-element-interactions — components/SongItem.tsx:22
   Static HTML elements with event handlers require a role.

49. [warning] nextjs-image-missing-sizes — components/SongItem.tsx:51
   next/image with fill but no sizes — the browser downloads the largest image. Add a sizes attribute for responsive behavior

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

51. [warning] server-sequential-independent-await — actions/getLikedSongs.ts:14
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

52. [warning] no-pure-black-background — components/Sidebar.tsx:55
   Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

⚠️ Warnings (52)

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

components/SearchInput.tsx:26
app/liked/components/LikedContent.tsx:26
components/ListItem.tsx:30
components/LikeButton.tsx:84
components/Header.tsx:37
components/Header.tsx:57
components/Header.tsx:72
components/Header.tsx:89
components/Header.tsx:105
components/Header.tsx:131
app/account/components/AccountContent.tsx:18
components/UploadModal.tsx:109
components/AuthModal.tsx:25

nextjs-image-missing-sizes

next/image with fill but no sizes — the browser downloads the largest image. Add a sizes attribute for responsive behavior

Add sizes for responsive behavior: sizes="(max-width: 768px) 100vw, 50vw" matching your layout breakpoints

app/liked/page.tsx:36
components/MediaItem.tsx:52
components/ListItem.tsx:52
components/SongItem.tsx:51

click-events-have-key-events

Enforce a clickable non-interactive element has at least one keyboard event listener.

Visible, non-interactive elements with click handlers must have one of keyup, keydown, or keypress listener.

components/PlayerContent.tsx:120
components/PlayerContent.tsx:160
components/MediaItem.tsx:30
components/SongItem.tsx:22

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/PlayerContent.tsx:120
components/PlayerContent.tsx:160
components/MediaItem.tsx:30
components/SongItem.tsx:22

no-pure-black-background

Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)

Tint the background slightly toward your brand hue — e.g. #0a0a0f or Tailwind's bg-gray-950. Pure black looks harsh on modern displays

components/Player.tsx:20
components/Header.tsx:56
components/Header.tsx:71
components/Sidebar.tsx:55

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)

components/SearchInput.tsx:26
app/liked/components/LikedContent.tsx:26
app/account/components/AccountContent.tsx:18

nextjs-missing-metadata

Page without metadata or generateMetadata export — hurts SEO

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

app/liked/page.tsx:1
app/(site)/page.tsx:1
app/search/page.tsx:1

design-no-redundant-size-axes

w-10 h-10 → use the shorthand size-10 (Tailwind v3.4+)

Collapse w-N h-N to size-N (Tailwind v3.4+) when both axes match

components/PlayerContent.tsx:122
components/PlayerContent.tsx:162
components/Modal.tsx:77

no-react19-deprecated-apis

useContext is superseded by use() on React 19+ — use() reads context conditionally inside hooks, branches, and loops; switch to import { use } from 'react'

Pass ref as a regular prop on function components — forwardRef is no longer needed in React 19+. Replace useContext(X) with use(X) for branch-aware context reads. Only enabled on projects detected as React 19+.

hooks/useUser.tsx:1
components/Input.tsx:1
components/Button.tsx:1

no-cascading-set-state

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

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

hooks/useUser.tsx:46
hooks/useGetSongById.ts:12

server-sequential-independent-await

Sequential await without a data dependency on the previous result — wrap the independent calls in Promise.all([...]) so they race instead of waterfalling

Wrap independent awaits in Promise.all([...]) so they race instead of waterfalling — second call doesn't depend on the first

app/layout.tsx:29
actions/getLikedSongs.ts:14

rendering-usetransition-loading

useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead

Replace with const [isPending, startTransition] = useTransition() — avoids a re-render for the loading state

hooks/useGetSongById.ts:8
components/UploadModal.tsx:18

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) or font-medium (500) on headings — 700+ crushes letter counter shapes at display sizes

app/liked/page.tsx:48

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

components/MediaItem.tsx:31

rerender-state-only-in-handlers

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

providers/ModalProvider.tsx:16

rendering-hydration-no-flicker

useEffect(setState, []) on mount causes a flash — consider useSyncExternalStore or suppressHydrationWarning

Use useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) or add suppressHydrationWarning to the element

providers/ModalProvider.tsx:18

no-effect-event-handler

useEffect simulating an event handler — move logic to an actual event handler instead

Move the conditional logic into onClick, onChange, or onSubmit handlers directly

components/AuthModal.tsx:23


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

Activity

0

No activity yet.