Fix the following React Review diagnostics in my codebase.
## Warnings (21)
1. [warning] no-danger — src/components/Chat/HighlightedCode.tsx:77
Do not use `dangerouslySetInnerHTML` prop
2. [warning] no-cascading-set-state — src/components/Chat/HighlightedCode.tsx:35
3 setState calls in a single useEffect — consider using useReducer or deriving state
3. [warning] js-batch-dom-css — src/components/Chat/InputArea.tsx:357
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
4. [warning] js-batch-dom-css — src/components/Chat/MessageBubble.tsx:321
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
5. [warning] js-batch-dom-css — src/components/Chat/MessageBubble.tsx:360
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
6. [warning] async-defer-await — src/hooks/useChat.ts:356
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
7. [warning] async-await-in-loop — src/hooks/useChat.ts:444
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
8. [warning] async-defer-await — src/hooks/useChat.ts:555
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
9. [warning] async-defer-await — src/hooks/useChat.ts:870
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
10. [warning] no-cascading-set-state — src/hooks/useChat.ts:1059
9 setState calls in a single useEffect — consider using useReducer or deriving state
11. [warning] no-fetch-in-effect — src/hooks/useChat.ts:1059
fetch() inside useEffect — use a data fetching library (react-query, SWR) or server component
12. [warning] async-defer-await — src/hooks/useChat.ts:1094
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
13. [warning] no-array-index-as-key — src/components/Chat/ToolCard.tsx:79
Array index "i" used as key — causes bugs when list is reordered or filtered
14. [warning] no-giant-component — src/components/Settings/SettingsPanel.tsx:214
Component "SettingsPanel" is 484 lines — consider breaking it into smaller focused components
15. [warning] no-giant-component — src/components/WorkspacePicker.tsx:130
Component "WorkspacePicker" is 450 lines — consider breaking it into smaller focused components
16. [warning] no-array-index-as-key — src/components/WorkspacePicker.tsx:408
Array index "i" used as key — causes bugs when list is reordered or filtered
17. [warning] no-render-in-render — src/components/Settings/ProviderCard.tsx:126
Inline render function "renderNameHint()" — extract to a separate component for proper reconciliation
18. [warning] js-set-map-lookups — src/components/Chat/MarkdownBlock.tsx:129
array.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups
19. [warning] no-giant-component — src/App.tsx:125
Component "AppContent" is 310 lines — consider breaking it into smaller focused components
20. [warning] prefer-useReducer — src/App.tsx:125
Component "AppContent" has 7 useState calls — consider useReducer for related state
21. [warning] async-defer-await — src/App.tsx:311
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
Copy as prompt
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 · 5 in 2 files
async-defer-awaitsrc/hooks/useChat.tssrc/App.tsxMultiple sequential element.style assignments — batch with cssText or classList for fewer reflows · 3 in 2 files
js-batch-dom-csssrc/components/Chat/MessageBubble.tsxsrc/components/Chat/InputArea.tsxComponent "SettingsPanel" is 484 lines — consider breaking it into smaller focused components · 3 in 3 files
no-giant-componentsrc/components/Settings/SettingsPanel.tsxsrc/components/WorkspacePicker.tsxsrc/App.tsx3 setState calls in a single useEffect — consider using useReducer or deriving state · 2 in 2 files
no-cascading-set-statesrc/components/Chat/HighlightedCode.tsxsrc/hooks/useChat.tsArray index "i" used as key — causes bugs when list is reordered or filtered · 2 in 2 files
no-array-index-as-keysrc/components/Chat/ToolCard.tsxsrc/components/WorkspacePicker.tsxDo not use `dangerouslySetInnerHTML` prop · 1 in 1 file
no-dangersrc/components/Chat/HighlightedCode.tsxawait inside a while-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently · 1 in 1 file
async-await-in-loopsrc/hooks/useChat.tsfetch() inside useEffect — use a data fetching library (react-query, SWR) or server component · 1 in 1 file
no-fetch-in-effectsrc/hooks/useChat.tsInline render function "renderNameHint()" — extract to a separate component for proper reconciliation · 1 in 1 file
no-render-in-rendersrc/components/Settings/ProviderCard.tsxarray.includes() in a loop is O(n) per call — convert to a Set for O(1) lookups · 1 in 1 file
js-set-map-lookupssrc/components/Chat/MarkdownBlock.tsxComponent "AppContent" has 7 useState calls — consider useReducer for related state · 1 in 1 file
prefer-useReducersrc/App.tsxReviewed by reactreview for commit b7b4c46. Configure here.