Skip to content

React Review Audit #395

@reactreview

Description

@reactreview
3 errors, ⚠️ 101 warnings 91 score
Copy as prompt
Fix the following React Review diagnostics in my codebase.

## Errors (3)

1. [error] no-unused-vars — apps/akari/__tests__/hooks/queries/useSearch.test.tsx:9
   Type alias 'SearchError' is declared but never used.

2. [error] no-unused-vars — apps/docs/src/components/MethodCard.tsx:22
   Parameter 'index' is declared but never used. Unused parameters should start with a '_'.

3. [error] no-unused-vars — apps/docs/src/components/MethodCard.tsx:22
   Parameter 'index' is declared but never used. Unused parameters should start with a '_'.

## Warnings (101)

4. [warning] prefer-useReducer — apps/akari/app/(auth)/oauth.tsx:29
   Component "OauthSignInScreen" has 5 useState calls — consider useReducer for related state

5. [warning] no-giant-component — apps/akari/app/(tabs)/messages/[convoId]/index.tsx:58
   Component "ConversationScreen" is 395 lines — consider breaking it into smaller focused components

6. [warning] prefer-useReducer — apps/akari/app/(tabs)/messages/[convoId]/index.tsx:58
   Component "ConversationScreen" has 7 useState calls — consider useReducer for related state

7. [warning] prefer-useReducer — apps/akari/app/(auth)/password.tsx:24
   Component "AuthScreen" has 5 useState calls — consider useReducer for related state

8. [warning] rendering-hydration-mismatch-time — apps/akari/app/(tabs)/community-notes/index.tsx:277
   new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

9. [warning] no-giant-component — apps/akari/app/debug.tsx:53
   Component "DebugScreen" is 301 lines — consider breaking it into smaller focused components

10. [warning] js-combine-iterations — apps/akari/components/GalleryView.tsx:57
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

11. [warning] prefer-useReducer — apps/akari/components/GifPicker.tsx:24
   Component "GifPicker" has 5 useState calls — consider useReducer for related state

12. [warning] prefer-useReducer — apps/akari/components/PostComposer.tsx:52
   Component "PostComposer" has 9 useState calls — consider useReducer for related state

13. [warning] no-giant-component — apps/akari/app/(tabs)/search/index.tsx:47
   Component "SearchScreen" is 316 lines — consider breaking it into smaller focused components

14. [warning] no-giant-component — apps/akari/app/(tabs)/settings/index.tsx:59
   Component "SettingsScreen" is 363 lines — consider breaking it into smaller focused components

15. [warning] js-combine-iterations — apps/akari/components/Sidebar.tsx:85
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

16. [warning] prefer-useReducer — apps/akari/components/ProfileView.tsx:46
   Component "ProfileView" has 5 useState calls — consider useReducer for related state

17. [warning] prefer-useReducer — apps/akari/components/ReviewComposer.tsx:62
   Component "ReviewComposer" has 7 useState calls — consider useReducer for related state

18. [warning] async-defer-await — apps/akari/components/post/StreamPlaceWebRTCPlayer.impl.native.tsx:137
   await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast

19. [warning] async-defer-await — apps/akari/components/post/StreamPlaceWebRTCPlayer.impl.native.tsx:118
   await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast

20. [warning] no-giant-component — apps/akari/components/moderation/OzoneActionSheet.tsx:94
   Component "OzoneActionSheet" is 379 lines — consider breaking it into smaller focused components

21. [warning] prefer-useReducer — apps/akari/components/moderation/OzoneActionSheet.tsx:102
   Component "OzoneActionSheet" has 13 useState calls — consider useReducer for related state

22. [warning] js-combine-iterations — apps/akari/components/moderation/OzoneActionSheet.tsx:548
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

23. [warning] js-combine-iterations — apps/akari/components/post/CommunityNoteContributor.tsx:73
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

24. [warning] js-set-map-lookups — apps/akari/components/post/PostTranslation.tsx:158
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

25. [warning] no-giant-component — apps/akari/components/ui/VirtualizedList.web.tsx:81
   Component "VirtualizedList" is 326 lines — consider breaking it into smaller focused components

26. [warning] prefer-use-effect-event — apps/akari/components/post/RepostSheet.tsx:73
   "onDismiss" is read only inside `addEventListener` — wrap it with useEffectEvent and remove it from the dep array so the effect doesn't re-synchronize on every parent render

27. [warning] query-mutation-missing-invalidation — apps/akari/hooks/mutations/useRateCommunityNote.ts:21
   useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

28. [warning] query-mutation-missing-invalidation — apps/akari/hooks/mutations/useSubmitCommunityNote.ts:36
   useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

29. [warning] query-mutation-missing-invalidation — apps/akari/hooks/mutations/useSubmitCommunityNote.ts:52
   useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

30. [warning] js-combine-iterations — apps/akari/hooks/queries/useNotifications.ts:102
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

31. [warning] js-combine-iterations — apps/akari/hooks/queries/useNotifications.ts:102
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

32. [warning] js-combine-iterations — apps/akari/hooks/queries/useOzoneQueue.ts:58
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

33. [warning] async-await-in-loop — apps/akari/hooks/useComposerDraft.ts:125
   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

34. [warning] js-batch-dom-css — apps/akari/hooks/useBodyScrollLock.ts:38
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

35. [warning] js-batch-dom-css — apps/akari/hooks/useBodyScrollLock.ts:51
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

36. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:223
   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

37. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:280
   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] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:324
   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

39. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:365
   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

40. [warning] async-await-in-loop — apps/firehose-notifier/src/notifier.ts:38
   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

41. [warning] no-redundant-roles — apps/docs/src/components/MethodCard.tsx:21
   The `ul` element has an implicit role of `list`. Defining this explicitly is redundant and should be avoided.

42. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:180
   Inline render function "renderParameterSignature()" — extract to a separate component for proper reconciliation

43. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:195
   Inline render function "renderSignatureModifiers()" — extract to a separate component for proper reconciliation

44. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:198
   Inline render function "renderSignatureParameters()" — extract to a separate component for proper reconciliation

45. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:235
   Inline render function "renderTypeBadges()" — extract to a separate component for proper reconciliation

46. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:254
   Inline render function "renderTypeBadges()" — extract to a separate component for proper reconciliation

47. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:256
   Inline render function "renderReturnDescription()" — extract to a separate component for proper reconciliation

48. [warning] async-await-in-loop — apps/akari/utils/ozoneAvatars.ts:28
   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

49. [warning] async-await-in-loop — apps/akari/utils/ozoneAvatars.ts:66
   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

50. [warning] js-combine-iterations — apps/firehose-notifier/src/subscription-utils.ts:7
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

51. [warning] js-combine-iterations — apps/notifier-registry/src/subscription-store.ts:39
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

52. [warning] server-sequential-independent-await — packages/bluesky-api/src/graph.test.ts:42
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

53. [warning] server-sequential-independent-await — packages/bluesky-api/src/graph.test.ts:81
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

54. [warning] no-barrel-import — packages/bluesky-api/src/index.test.ts:1
   Import from barrel/index file — import directly from the source module for better tree-shaking

55. [warning] server-sequential-independent-await — packages/bluesky-api/src/feeds.test.ts:333
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

56. [warning] prefer-useReducer — apps/akari/app/(auth)/oauth.tsx:29
   Component "OauthSignInScreen" has 5 useState calls — consider useReducer for related state

57. [warning] prefer-useReducer — apps/akari/app/(auth)/password.tsx:24
   Component "AuthScreen" has 5 useState calls — consider useReducer for related state

58. [warning] rendering-hydration-mismatch-time — apps/akari/app/(tabs)/community-notes/index.tsx:277
   new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

59. [warning] no-giant-component — apps/akari/app/(tabs)/messages/[convoId]/index.tsx:58
   Component "ConversationScreen" is 395 lines — consider breaking it into smaller focused components

60. [warning] prefer-useReducer — apps/akari/app/(tabs)/messages/[convoId]/index.tsx:58
   Component "ConversationScreen" has 7 useState calls — consider useReducer for related state

61. [warning] no-giant-component — apps/akari/app/(tabs)/search/index.tsx:47
   Component "SearchScreen" is 316 lines — consider breaking it into smaller focused components

62. [warning] prefer-useReducer — apps/akari/components/GifPicker.tsx:24
   Component "GifPicker" has 5 useState calls — consider useReducer for related state

63. [warning] prefer-useReducer — apps/akari/components/PostComposer.tsx:52
   Component "PostComposer" has 9 useState calls — consider useReducer for related state

64. [warning] no-giant-component — apps/akari/app/(tabs)/settings/index.tsx:59
   Component "SettingsScreen" is 363 lines — consider breaking it into smaller focused components

65. [warning] js-combine-iterations — apps/akari/components/GalleryView.tsx:57
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

66. [warning] no-giant-component — apps/akari/app/debug.tsx:53
   Component "DebugScreen" is 301 lines — consider breaking it into smaller focused components

67. [warning] prefer-useReducer — apps/akari/components/ReviewComposer.tsx:62
   Component "ReviewComposer" has 7 useState calls — consider useReducer for related state

68. [warning] no-giant-component — apps/akari/components/moderation/OzoneActionSheet.tsx:94
   Component "OzoneActionSheet" is 379 lines — consider breaking it into smaller focused components

69. [warning] prefer-useReducer — apps/akari/components/moderation/OzoneActionSheet.tsx:102
   Component "OzoneActionSheet" has 13 useState calls — consider useReducer for related state

70. [warning] js-combine-iterations — apps/akari/components/moderation/OzoneActionSheet.tsx:548
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

71. [warning] prefer-useReducer — apps/akari/components/ProfileView.tsx:46
   Component "ProfileView" has 5 useState calls — consider useReducer for related state

72. [warning] js-combine-iterations — apps/akari/components/Sidebar.tsx:85
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

73. [warning] prefer-use-effect-event — apps/akari/components/post/RepostSheet.tsx:73
   "onDismiss" is read only inside `addEventListener` — wrap it with useEffectEvent and remove it from the dep array so the effect doesn't re-synchronize on every parent render

74. [warning] js-combine-iterations — apps/akari/components/post/CommunityNoteContributor.tsx:73
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

75. [warning] no-giant-component — apps/akari/components/ui/VirtualizedList.web.tsx:81
   Component "VirtualizedList" is 326 lines — consider breaking it into smaller focused components

76. [warning] js-set-map-lookups — apps/akari/components/post/PostTranslation.tsx:158
   array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups

77. [warning] async-defer-await — apps/akari/components/post/StreamPlaceWebRTCPlayer.impl.native.tsx:137
   await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast

78. [warning] async-defer-await — apps/akari/components/post/StreamPlaceWebRTCPlayer.impl.native.tsx:118
   await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast

79. [warning] query-mutation-missing-invalidation — apps/akari/hooks/mutations/useSubmitCommunityNote.ts:36
   useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

80. [warning] query-mutation-missing-invalidation — apps/akari/hooks/mutations/useSubmitCommunityNote.ts:52
   useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

81. [warning] query-mutation-missing-invalidation — apps/akari/hooks/mutations/useRateCommunityNote.ts:21
   useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh)

82. [warning] js-combine-iterations — apps/akari/hooks/queries/useNotifications.ts:102
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

83. [warning] js-combine-iterations — apps/akari/hooks/queries/useNotifications.ts:102
   .filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of

84. [warning] js-batch-dom-css — apps/akari/hooks/useBodyScrollLock.ts:38
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

85. [warning] js-batch-dom-css — apps/akari/hooks/useBodyScrollLock.ts:51
   Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows

86. [warning] js-combine-iterations — apps/akari/hooks/queries/useOzoneQueue.ts:58
   .map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of

87. [warning] async-await-in-loop — apps/akari/hooks/useComposerDraft.ts:125
   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

88. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:223
   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

89. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:280
   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

90. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:324
   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

91. [warning] async-await-in-loop — apps/akari/utils/followingCleanupController.ts:365
   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

92. [warning] async-await-in-loop — apps/akari/utils/ozoneAvatars.ts:28
   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

93. [warning] async-await-in-loop — apps/akari/utils/ozoneAvatars.ts:66
   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

94. [warning] no-redundant-roles — apps/docs/src/components/MethodCard.tsx:21
   The `ul` element has an implicit role of `list`. Defining this explicitly is redundant and should be avoided.

95. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:180
   Inline render function "renderParameterSignature()" — extract to a separate component for proper reconciliation

96. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:195
   Inline render function "renderSignatureModifiers()" — extract to a separate component for proper reconciliation

97. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:198
   Inline render function "renderSignatureParameters()" — extract to a separate component for proper reconciliation

98. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:235
   Inline render function "renderTypeBadges()" — extract to a separate component for proper reconciliation

99. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:254
   Inline render function "renderTypeBadges()" — extract to a separate component for proper reconciliation

100. [warning] no-render-in-render — apps/docs/src/components/MethodCard.tsx:256
   Inline render function "renderReturnDescription()" — extract to a separate component for proper reconciliation

101. [warning] no-barrel-import — packages/bluesky-api/src/index.test.ts:1
   Import from barrel/index file — import directly from the source module for better tree-shaking

102. [warning] server-sequential-independent-await — packages/bluesky-api/src/feeds.test.ts:333
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

103. [warning] server-sequential-independent-await — packages/bluesky-api/src/graph.test.ts:42
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

104. [warning] server-sequential-independent-await — packages/bluesky-api/src/graph.test.ts:81
   Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling

❌ Errors (3)

Type alias 'SearchError' is declared but never used. · 3 in 2 files

no-unused-vars

Consider removing this declaration.

File Lines
apps/docs/src/components/MethodCard.tsx 22, 22
apps/akari/__tests__/hooks/queries/useSearch.test.tsx 9

⚠️ Warnings (101)

Component "OauthSignInScreen" has 5 useState calls — consider useReducer for related state · 16 in 8 files

prefer-useReducer

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

File Lines
apps/akari/app/(auth)/oauth.tsx 29, 29
apps/akari/app/(tabs)/messages/[convoId]/index.tsx 58, 58
apps/akari/app/(auth)/password.tsx 24, 24
apps/akari/components/GifPicker.tsx 24, 24
apps/akari/components/PostComposer.tsx 52, 52
…and 3 more files view on react.review
.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of · 16 in 8 files

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/akari/hooks/queries/useNotifications.ts 102, 102, 102, 102
apps/akari/components/GalleryView.tsx 57, 57
apps/akari/components/Sidebar.tsx 85, 85
apps/akari/components/moderation/OzoneActionSheet.tsx 548, 548
apps/akari/components/post/CommunityNoteContributor.tsx 73, 73
…and 3 more files 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 · 15 in 4 files

async-await-in-loop

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

File Lines
apps/akari/utils/followingCleanupController.ts 223, 223, 280, 280, 324, 324, 365, 365
apps/akari/utils/ozoneAvatars.ts 28, 28, 66, 66
apps/akari/hooks/useComposerDraft.ts 125, 125
apps/firehose-notifier/src/notifier.ts 38
Component "ConversationScreen" is 395 lines — consider breaking it into smaller focused components · 12 in 6 files

no-giant-component

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

File Lines
apps/akari/app/(tabs)/messages/[convoId]/index.tsx 58, 58
apps/akari/app/debug.tsx 53, 53
apps/akari/app/(tabs)/search/index.tsx 47, 47
apps/akari/app/(tabs)/settings/index.tsx 59, 59
apps/akari/components/moderation/OzoneActionSheet.tsx 94, 94
…and 1 more file view on react.review
Inline render function "renderParameterSignature()" — extract to a separate component for proper reconciliation · 12 in 1 file

no-render-in-render

Extract to a named component: const ListItem = ({ item }) => <div>{item.name}</div>

File Lines
apps/docs/src/components/MethodCard.tsx 180, 180, 195, 195, 198, 198, 235, 235, +4 more
useMutation without a cache update — stale data may remain after the mutation. Call queryClient.invalidateQueries / setQueryData / resetQueries / refetchQueries inside onSuccess (or trigger a router refresh) · 6 in 2 files

query-mutation-missing-invalidation

Add onSuccess: () => queryClient.invalidateQueries({ queryKey: ['...'] }) so cached data stays in sync after the mutation

File Lines
apps/akari/hooks/mutations/useSubmitCommunityNote.ts 36, 36, 52, 52
apps/akari/hooks/mutations/useRateCommunityNote.ts 21, 21
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling · 6 in 2 files

server-sequential-independent-await

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

File Lines
packages/bluesky-api/src/graph.test.ts 42, 42, 81, 81
packages/bluesky-api/src/feeds.test.ts 333, 333
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast · 4 in 1 file

async-defer-await

Move the await after the synchronous early-return guard so the skip path stays fast

File Lines
apps/akari/components/post/StreamPlaceWebRTCPlayer.impl.native.tsx 118, 118, 137, 137
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows · 4 in 1 file

js-batch-dom-css

Batch DOM/CSS reads and writes — interleaving them inside a loop causes layout thrashing. Read first, then write

File Lines
apps/akari/hooks/useBodyScrollLock.ts 38, 38, 51, 51
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional · 2 in 1 file

rendering-hydration-mismatch-time

Wrap dynamic time/random values in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

File Lines
apps/akari/app/(tabs)/community-notes/index.tsx 277, 277
array.indexOf() in a loop is O(n) per call — convert to a Set for O(1) lookups · 2 in 1 file

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/akari/components/post/PostTranslation.tsx 158, 158
"onDismiss" is read only inside `addEventListener` — wrap it with useEffectEvent and remove it from the dep array so the effect doesn't re-synchronize on every parent render · 2 in 1 file

prefer-use-effect-event

Wrap the callback with useEffectEvent(callback) (React 19+) and call the resulting binding from inside the sub-handler. The Effect Event captures the latest props/state without being a reactive dep, so the effect doesn't re-subscribe on every parent render. See https://react.dev/reference/react/useEffectEvent

File Lines
apps/akari/components/post/RepostSheet.tsx 73, 73
The `ul` element has an implicit role of `list`. Defining this explicitly is redundant and should be avoided. · 2 in 1 file

no-redundant-roles

Remove the redundant role list from the element ul.

File Lines
apps/docs/src/components/MethodCard.tsx 21, 21
Import from barrel/index file — import directly from the source module for better tree-shaking · 2 in 1 file

no-barrel-import

Import from the direct path: import { Button } from './components/Button' instead of ./components

File Lines
packages/bluesky-api/src/index.test.ts 1, 1

Reviewed by reactreview for commit 0ef8a35. Configure here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions