Skip to content

React Review Audit #1

Description

@react-doctor
1 error, ⚠️ 46 warnings 91 score
Copy as prompt
Fix the following React Review diagnostics in my codebase.

## Errors (1)

1. [error] no-nested-component-definition — apps/website/public/budge.iife.js:16363
   Component "C" defined inside "Pu" — creates new instance every render, destroying state

## Warnings (46)

2. [warning] no-giant-component — apps/website/app/terms/page.tsx:8
   Component "TermsPage" is 350 lines — consider breaking it into smaller focused components

3. [warning] no-giant-component — apps/website/components/budge-me-paper-preview.tsx:489
   Component "BudgeMePaperPreview" is 961 lines — consider breaking it into smaller focused components

4. [warning] prefer-useReducer — apps/website/components/budge-me-paper-preview.tsx:492
   Component "BudgeMePaperPreview" has 18 useState calls — consider useReducer for related state

5. [warning] no-cascading-set-state — apps/website/components/budge-me-paper-preview.tsx:547
   6 setState calls in a single useEffect — consider using useReducer or deriving state

6. [warning] no-cascading-set-state — apps/website/components/budge-me-paper-preview.tsx:751
   25 setState calls in a single useEffect — consider using useReducer or deriving state

7. [warning] no-cascading-set-state — apps/website/components/budge-me-paper-preview.tsx:856
   19 setState calls in a single useEffect — consider using useReducer or deriving state

8. [warning] async-await-in-loop — apps/website/components/budge-me-paper-preview.tsx:895
   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

9. [warning] async-await-in-loop — apps/website/components/budge-me-paper-preview.tsx:895
   await inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently

10. [warning] async-await-in-loop — apps/website/components/budge-me-paper-preview.tsx:916
   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

11. [warning] async-await-in-loop — apps/website/components/budge-me-paper-preview.tsx:933
   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

12. [warning] no-giant-component — apps/website/app/__budge.tsx:373
   Component "BudgeRuntime" is 352 lines — consider breaking it into smaller focused components

13. [warning] no-cascading-set-state — apps/website/app/__budge.tsx:445
   3 setState calls in a single useEffect — consider using useReducer or deriving state

14. [warning] no-cascading-set-state — apps/website/app/__budge.tsx:480
   6 setState calls in a single useEffect — consider using useReducer or deriving state

15. [warning] no-cascading-set-state — apps/website/app/__budge.tsx:493
   3 setState calls in a single useEffect — consider using useReducer or deriving state

16. [warning] no-cascading-set-state — apps/website/app/__budge.tsx:551
   15 setState calls in a single useEffect — consider using useReducer or deriving state

17. [warning] no-giant-component — apps/website/components/replay/replay-viewer.tsx:375
   Component "ReplayViewer" is 1015 lines — consider breaking it into smaller focused components

18. [warning] no-cascading-set-state — apps/website/components/budge-logo.tsx:81
   8 setState calls in a single useEffect — consider using useReducer or deriving state

19. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:1361
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

20. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:1362
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

21. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:1375
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

22. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:2045
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

23. [warning] js-cache-property-access — apps/website/public/budge.iife.js:4099
   t.memoizedProps.revealOrder is read 4 times inside this loop — hoist into a const at the top of the loop body

24. [warning] no-giant-component — apps/website/public/budge.iife.js:6373
   Component "Hc" is 326 lines — consider breaking it into smaller focused components

25. [warning] js-cache-property-access — apps/website/public/budge.iife.js:10318
   n.style.display is read 3 times inside this loop — hoist into a const at the top of the loop body

26. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:12149
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

27. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:12402
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

28. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:12403
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

29. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:12413
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

30. [warning] js-combine-iterations — apps/website/public/budge.iife.js:12575
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

31. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:12967
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

32. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:14050
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

33. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:14338
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

34. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:14347
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

35. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:15067
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

36. [warning] no-giant-component — apps/website/public/budge.iife.js:18209
   Component "Bp" is 729 lines — consider breaking it into smaller focused components

37. [warning] no-many-boolean-props — apps/website/public/budge.iife.js:18998
   Component "Up" takes 4 boolean-like props (isProjecting, isProjectionDirty, isSharedProjectionDirty…) — consider compound components or explicit variants instead of stacking flags

38. [warning] rerender-memo-with-default-value — apps/website/public/budge.iife.js:19326
   Default prop value {} creates a new object reference every render — extract to a module-level constant

39. [warning] js-hoist-intl — apps/website/public/budge.iife.js:20039
   new Intl.Segmenter() inside a function — hoist to module scope or wrap in useMemo so it isn't recreated each call

40. [warning] js-set-map-lookups — apps/website/public/budge.iife.js:21437
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

41. [warning] no-giant-component — apps/website/public/budge.iife.js:21644
   Component "Z_" is 599 lines — consider breaking it into smaller focused components

42. [warning] js-tosorted-immutable — packages/budge/src/widget.tsx:372
   [...array].sort() — use array.toSorted() for immutable sorting (ES2023)

43. [warning] js-set-map-lookups — packages/budge/src/widget.tsx:379
   array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups

44. [warning] no-giant-component — packages/budge/src/widget.tsx:652
   Component "Budge" is 762 lines — consider breaking it into smaller focused components

45. [warning] prefer-useReducer — packages/budge/src/widget.tsx:655
   Component "Budge" has 12 useState calls — consider useReducer for related state

46. [warning] no-cascading-set-state — packages/budge/src/widget.tsx:744
   7 setState calls in a single useEffect — consider using useReducer or deriving state

47. [warning] no-cascading-set-state — packages/budge/src/widget.tsx:1082
   21 setState calls in a single useEffect — consider using useReducer or deriving state

❌ Errors (1)

Component "C" defined inside "Pu" — creates new instance every render, destroying state · 1 in 1 file

no-nested-component-definition

Move to a separate file or to module scope above the parent component

File Lines
apps/website/public/budge.iife.js 16363

⚠️ Warnings (46)

array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups · 15 in 2 files

js-set-map-lookups

Use a Set or Map for repeated membership tests / keyed lookups — Array.includes/find is O(n) per call

File Lines
apps/website/public/budge.iife.js 1361, 1362, 1375, 2045, 12149, 12402, 12403, 12413, +6 more
packages/budge/src/widget.tsx 379
6 setState calls in a single useEffect — consider using useReducer or deriving state · 10 in 4 files

no-cascading-set-state

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

File Lines
apps/website/app/__budge.tsx 445, 480, 493, 551
apps/website/components/budge-me-paper-preview.tsx 547, 751, 856
packages/budge/src/widget.tsx 744, 1082
apps/website/components/budge-logo.tsx 81
Component "TermsPage" is 350 lines — consider breaking it into smaller focused components · 8 in 6 files

no-giant-component

Extract logical sections into focused components: <UserHeader />, <UserActions />, etc.

File Lines
apps/website/public/budge.iife.js 6373, 18209, 21644
apps/website/app/terms/page.tsx 8
apps/website/components/budge-me-paper-preview.tsx 489
apps/website/app/__budge.tsx 373
apps/website/components/replay/replay-viewer.tsx 375
…and 1 more file view on react.review
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 in 1 file

async-await-in-loop

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

File Lines
apps/website/components/budge-me-paper-preview.tsx 895, 895, 916, 933
Component "BudgeMePaperPreview" has 18 useState calls — consider useReducer for related state · 2 in 2 files

prefer-useReducer

Group related state: const [state, dispatch] = useReducer(reducer, { field1, field2, ... })

File Lines
apps/website/components/budge-me-paper-preview.tsx 492
packages/budge/src/widget.tsx 655
t.memoizedProps.revealOrder is read 4 times inside this loop — hoist into a const at the top of the loop body · 2 in 1 file

js-cache-property-access

Hoist the deep member access into a const at the top of the loop body: const { x, y } = obj.deeply.nested

File Lines
apps/website/public/budge.iife.js 4099, 10318
.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of · 1 in 1 file

js-combine-iterations

Combine .map().filter() (or similar chains) into a single pass with .reduce() or a for...of loop to avoid iterating the array twice

File Lines
apps/website/public/budge.iife.js 12575
Component "Up" takes 4 boolean-like props (isProjecting, isProjectionDirty, isSharedProjectionDirty…) — consider compound components or explicit variants instead of stacking flags · 1 in 1 file

no-many-boolean-props

Split into compound components or named variants: <Button.Primary />, <DialogConfirm /> instead of stacking isPrimary, isConfirm flags

File Lines
apps/website/public/budge.iife.js 18998
Default prop value {} creates a new object reference every render — extract to a module-level constant · 1 in 1 file

rerender-memo-with-default-value

Move to module scope: const EMPTY_ITEMS: Item[] = [] then use as the default value

File Lines
apps/website/public/budge.iife.js 19326
new Intl.Segmenter() inside a function — hoist to module scope or wrap in useMemo so it isn't recreated each call · 1 in 1 file

js-hoist-intl

Hoist new Intl.NumberFormat(...) to module scope or wrap in useMemo — Intl constructors allocate dozens of objects per locale lookup

File Lines
apps/website/public/budge.iife.js 20039
[...array].sort() — use array.toSorted() for immutable sorting (ES2023) · 1 in 1 file

js-tosorted-immutable

Use array.toSorted() (ES2023) instead of [...array].sort() for immutable sorting without the spread allocation

File Lines
packages/budge/src/widget.tsx 372

Reviewed by reactreview for commit 087c34c. Configure here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions