React Review Audit
Author: react-doctor[bot]Created May 18, 2026Updated May 20, 2026
| ❌ 10 errors, ⚠️ 228 warnings |
Fix the following React Review diagnostics in my codebase.
## Errors (10)
1. [error] jsx-key — packages/scan/src/web/views/notifications/collapsed-event.tsx:165
Missing "key" prop for element in iterator.
2. [error] no-mutable-in-deps — packages/scan/src/web/views/notifications/popover.tsx:73
"triggerRef.current" in deps — refs are mutable and don't trigger re-renders, so React won't re-run this effect when it changes. Read the ref inside the effect body instead
3. [error] effect-needs-cleanup — packages/scan/src/web/views/notifications/notifications.tsx:227
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(...)
4. [error] effect-needs-cleanup — packages/scan/src/web/views/notifications/slowdown-history.tsx:27
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(...)
5. [error] effect-needs-cleanup — packages/scan/src/web/views/notifications/slowdown-history.tsx:339
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(...)
6. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
Async client component "B" — client components cannot be async
7. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
Async client component "Pa" — client components cannot be async
8. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
Async client component "Ul" — client components cannot be async
9. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
Async client component "Jl" — client components cannot be async
10. [error] nextjs-async-client-component — packages/website/public/auto.global.js:2
Async client component "Tc" — client components cannot be async
## Warnings (228)
11. [warning] no-cascading-set-state — kitchen-sink/src/examples/sierpinski/index.tsx:27
3 setState calls in a single useEffect — consider using useReducer or deriving state
12. [warning] click-events-have-key-events — kitchen-sink/src/examples/e2e-fixture/index.tsx:46
Enforce a clickable non-interactive element has at least one keyboard event listener.
13. [warning] no-static-element-interactions — kitchen-sink/src/examples/e2e-fixture/index.tsx:46
Static HTML elements with event handlers require a role.
14. [warning] no-react19-deprecated-apis — kitchen-sink/src/examples/e2e-fixture/index.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'`
15. [warning] no-uncontrolled-input — kitchen-sink/src/examples/todo-list/index.tsx:92
<input value={...}> with no `onChange` or `readOnly` — React renders this as a silently read-only field
16. [warning] rerender-functional-setstate — kitchen-sink/src/examples/todo-list/index.tsx:88
setIndex(index + ...) — use functional update to avoid stale closures
17. [warning] iframe-has-title — kitchen-sink/src/main.tsx:39
Missing `title` attribute for the `iframe` element.
18. [warning] design-no-default-tailwind-palette — kitchen-sink/src/main.tsx:19
border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
19. [warning] design-no-bold-heading — kitchen-sink/src/main.tsx:20
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
20. [warning] design-no-default-tailwind-palette — kitchen-sink/src/main.tsx:24
border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
21. [warning] design-no-default-tailwind-palette — kitchen-sink/src/main.tsx:29
border-gray-950 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
22. [warning] js-batch-dom-css — packages/extension/src/inject/notification.ts:36
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
23. [warning] js-batch-dom-css — packages/extension/src/inject/notification.ts:130
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
24. [warning] js-set-map-lookups — packages/scan/src/core/index.ts:299
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups
25. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:172
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
26. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:176
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
27. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:177
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
28. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:178
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
29. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:179
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
30. [warning] js-batch-dom-css — packages/scan/src/core/notifications/outline-overlay.ts:195
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
31. [warning] no-pure-black-background — packages/scan/src/web/toolbar.tsx:22
Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)
32. [warning] no-pure-black-background — packages/scan/src/web/toolbar.tsx:27
Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)
33. [warning] no-giant-component — packages/scan/src/web/views/inspector/components-tree/index.tsx:386
Component "ComponentsTree" is 792 lines — consider breaking it into smaller focused components
34. [warning] design-no-redundant-size-axes — packages/scan/src/web/views/inspector/components-tree/index.tsx:1072
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
35. [warning] design-no-redundant-size-axes — packages/scan/src/web/views/inspector/components-tree/index.tsx:1086
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
36. [warning] design-no-redundant-size-axes — packages/scan/src/web/views/inspector/components-tree/index.tsx:1102
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
37. [warning] async-await-in-loop — packages/scan/src/new-outlines/index.ts:153
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
38. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:304
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
39. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:305
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
40. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:306
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
41. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:307
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
42. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:318
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
43. [warning] js-batch-dom-css — packages/scan/src/new-outlines/index.ts:381
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
44. [warning] client-passive-event-listeners — packages/scan/src/new-outlines/index.ts:407
"scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())
45. [warning] rerender-transitions-scroll — packages/scan/src/new-outlines/index.ts:411
setState in a "scroll" handler triggers re-renders at scroll/pointer frequency — wrap in startTransition (mark as non-urgent), use useDeferredValue, or stash in a ref + rAF throttle
46. [warning] js-flatmap-filter — packages/scan/src/web/views/inspector/timeline/utils.ts:148
.map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass
47. [warning] no-cascading-set-state — packages/scan/src/web/views/notifications/collapsed-event.tsx:36
11 setState calls in a single useEffect — consider using useReducer or deriving state
48. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1357
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups
49. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1394
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups
50. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1446
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups
51. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1865
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups
52. [warning] js-set-map-lookups — packages/scan/src/web/views/inspector/utils.ts:1888
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups
53. [warning] js-tosorted-immutable — packages/scan/src/polyfills.ts:4
[...array].sort() — use array.toSorted() for immutable sorting (ES2023)
54. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:5
Unknown property found
55. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:5
Unknown property found
56. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:5
Unknown property found
57. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:18
Unknown property found
58. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:18
Unknown property found
59. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:18
Unknown property found
60. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:23
Unknown property found
61. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:23
Unknown property found
62. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:23
Unknown property found
63. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:27
Unknown property found
64. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:27
Unknown property found
65. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:27
Unknown property found
66. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:31
Unknown property found
67. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:31
Unknown property found
68. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:31
Unknown property found
69. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:36
Unknown property found
70. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:36
Unknown property found
71. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:36
Unknown property found
72. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:45
Unknown property found
73. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:45
Unknown property found
74. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:45
Unknown property found
75. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:51
Unknown property found
76. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:51
Unknown property found
77. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:51
Unknown property found
78. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:56
Unknown property found
79. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:56
Unknown property found
80. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:56
Unknown property found
81. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:60
Unknown property found
82. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:60
Unknown property found
83. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:60
Unknown property found
84. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:64
Unknown property found
85. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:64
Unknown property found
86. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:64
Unknown property found
87. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:72
Unknown property found
88. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:72
Unknown property found
89. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:72
Unknown property found
90. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:78
Unknown property found
91. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:78
Unknown property found
92. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:78
Unknown property found
93. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:84
Unknown property found
94. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:84
Unknown property found
95. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:84
Unknown property found
96. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:89
Unknown property found
97. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:89
Unknown property found
98. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:89
Unknown property found
99. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:94
Unknown property found
100. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:94
Unknown property found
101. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:94
Unknown property found
102. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:99
Unknown property found
103. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:99
Unknown property found
104. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:99
Unknown property found
105. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:104
Unknown property found
106. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:104
Unknown property found
107. [warning] no-unknown-property — packages/scan/src/web/components/svg-sprite/index.tsx:104
Unknown property found
108. [warning] js-cache-property-access — packages/scan/src/web/views/inspector/whats-changed/use-change-store.ts:123
aggregatedChanges.contextChanges.set is read 3 times inside this loop — hoist into a const at the top of the loop body
109. [warning] js-cache-property-access — packages/scan/src/web/views/inspector/whats-changed/use-change-store.ts:128
change.contextType.toString is read 3 times inside this loop — hoist into a const at the top of the loop body
110. [warning] design-no-default-tailwind-palette — packages/scan/src/web/views/inspector/diff-value.tsx:55
text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
111. [warning] design-no-default-tailwind-palette — packages/scan/src/web/views/inspector/diff-value.tsx:81
text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
112. [warning] design-no-default-tailwind-palette — packages/scan/src/web/views/inspector/diff-value.tsx:118
text-gray-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
113. [warning] no-array-index-as-key — packages/scan/src/web/views/inspector/diff-value.tsx:143
Array index "index" used as key — causes bugs when list is reordered or filtered
114. [warning] js-flatmap-filter — packages/scan/src/core/notifications/event-tracking.ts:290
.map().filter(Boolean) iterates twice — use .flatMap() to transform and filter in a single pass
115. [warning] no-giant-component — packages/scan/src/web/views/inspector/overlay/index.tsx:48
Component "ScanOverlay" is 684 lines — consider breaking it into smaller focused components
116. [warning] no-cascading-set-state — packages/scan/src/web/views/inspector/what-changed.tsx:36
3 setState calls in a single useEffect — consider using useReducer or deriving state
117. [warning] js-combine-iterations — packages/scan/src/web/views/inspector/what-changed.tsx:49
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
118. [warning] no-render-in-render — packages/scan/src/web/views/inspector/what-changed.tsx:323
Inline render function "renderName()" — extract to a separate component for proper reconciliation
119. [warning] no-array-index-as-key — packages/scan/src/web/views/inspector/what-changed.tsx:452
Array index "i" used as key — causes bugs when list is reordered or filtered
120. [warning] js-batch-dom-css — packages/scan/src/web/views/inspector/flash-overlay.ts:64
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
121. [warning] js-batch-dom-css — packages/scan/src/web/views/inspector/flash-overlay.ts:68
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
122. [warning] no-unknown-property — packSource: aidenybai/react-scan