Skip to content

DO NOT MERGE — React useEffect audit (HIGH + MEDIUM priority)#1408

Draft
simple-agent-manager[bot] wants to merge 4 commits into
mainfrom
sam/implement-react-useeffect-audit-01kvz4
Draft

DO NOT MERGE — React useEffect audit (HIGH + MEDIUM priority)#1408
simple-agent-manager[bot] wants to merge 4 commits into
mainfrom
sam/implement-react-useeffect-audit-01kvz4

Conversation

@simple-agent-manager

Copy link
Copy Markdown
Contributor

DO NOT MERGE

This is a draft PR for review only. It implements the React useEffect audit checklist (HIGH and MEDIUM priority items).

Summary

Systematic audit of 350 useEffect instances across 189 files. This PR addresses ~136 items (30 HIGH + ~106 MEDIUM priority), leaving LOW priority items and "Keep" items for a follow-up.

Patterns Applied

Pattern Count Description
useSyncExternalStore 4 Media query hooks (useIsMobile, useIsStandalone, usePrefersReducedMotion, ThemeContext)
Shared useMediaQuery hook 1 new Consolidates 3+ instances of identical useState+useEffect media query pattern into packages/ui
Latest-ref pattern 2 useEscapeKey, useClickOutside — stabilize callbacks without effect resubscription
Render derivation ~20 Replace prop-to-state sync effects with useMemo/inline computation
Event-handler ownership ~15 Move side effects from useEffect into the handler that triggers them
Keyed remount 2 TriggerForm, SkillFormDialog — reset form state via React key instead of sync effects
AbortController cleanup ~10 Replace boolean cancelled flags with proper AbortController in async effects
Ref stabilization ~15 Break dependency cycles by reading volatile values from refs

New Shared Code

  • packages/ui/src/hooks/useMediaQuery.tsuseSyncExternalStore-based media query hook
  • packages/ui/tests/useMediaQuery.test.ts — 5 tests
  • packages/ui/tests/useEscapeKey.test.ts — 5 tests (including latest-ref verification)
  • packages/ui/tests/useClickOutside.test.ts — 5 tests (including latest-ref verification)

Files Modified

90 files changed, 1831 insertions, 1748 deletions across:

  • apps/web/ — components, hooks, pages, tests
  • packages/ui/ — new hook + tests, Dialog refactor
  • packages/acp-client/ — hooks refactor
  • packages/terminal/ — terminal component refactor

Quality Status

Check Status Notes
Typecheck ✅ Pass All 16 tasks
Build ✅ Pass All 9 tasks
Tests ✅ Pass 2409/2414 pass; 5 failures are pre-existing on main (project-message-view.test.tsx timing + tooltip issues)
Lint ⚠️ 3 pre-existing import-sort errors on main (not from this PR)

Checklist Coverage

HIGH Priority (30 items) — All addressed

  • UE-001 through UE-030 — implemented across 3 commits

MEDIUM Priority (~106 items) — All addressed

  • Implemented in the third commit via 5 parallel subagents
  • 2 subagent changes reverted (OnboardingContext, DeploymentSettings) due to behavioral regressions

LOW Priority (~113 items) — Deferred

  • Most are "keep but consider extracting into hook" — minor cleanup
  • Can be addressed in a follow-up PR

Keep (101 items) — No changes needed

  • True external synchronization effects — correctly using useEffect

Known Risks

  • useSyncExternalStore changes subscription model (always subscribed vs conditional) — tests updated to match
  • Keyed remount pattern for forms changes re-render behavior — tested via existing test suites
  • Terminal component refactor touched complex xterm.js lifecycle code — manual verification recommended

🤖 Generated with Claude Code

raphaeltm and others added 4 commits June 25, 2026 10:38
Shared hooks:
- Add useMediaQuery (useSyncExternalStore) to packages/ui
- Refactor useEscapeKey, useClickOutside with latest-ref pattern
- Refactor usePrefersReducedMotion to useSyncExternalStore
- Simplify useIsMobile, useIsStandalone, ThemeContext via useMediaQuery

Forms/prop-sync (remove prop-to-state mirroring):
- ProjectAgentCard, ProjectAgentsSection, ScalingSettings
- ProfileFormDialog, TriggerForm

Render derivation (replace effects with useMemo/derived state):
- GlobalCommandPalette, RepoSelector, AccountMap, useMapFilters
- useProjectChatState, useWorkspaceCore

Network/query (add abort controllers, remove mountedRef):
- useAgentChat, FilePreviewModal, useSessionLifecycle
- ChatFilePanel, GitDiffView, useAdminAnalytics, useAdminErrors
- useAdminHealth, useAdminLogQuery, useNodeLogs, useNodeSystemInfo
- useWorkspacePorts, useBootLogStream, AppShell

Lifecycle/timer (clean up intervals, fix race conditions):
- ChatSession, OrphanedSessionsBanner, project-message-view
- useTrialDraft, workspace/index, useProjectChatState

Terminal/acp-client:
- MultiTerminal, Terminal, useTerminalSessions, AgentPanel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- OnboardingContext: split fetch into focused hook with abort
- CreateWorkspace: split mount effect into focused data hooks
- project-message-view-recovery test: remove test-only mirror hook
- MentionPalette, SlashCommandPalette: latest-ref pattern
- TriggerForm: remove unused useMemo import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MEDIUM priority refactors (~50 files):
- Forms/prop-sync: AgentSettingsCard, SkillFormDialog, SchedulePicker,
  ObservabilityFilters, ConfigurationSection, LogFilters
- Network/abort: Nodes, Project, ProjectLibrary, ProjectNotifications,
  ProjectTasks, IdeaDetailPage, MemoryTab, useActiveTasks, useAgentProfiles,
  useNotifications, useTokenRefresh, TriggerDropdown, useSessionTimeline,
  useConnectionRecovery
- Chat/lifecycle: ChatSession (activity/usage to handlers), ProjectChatComposer
  (latest-ref), WorkspaceChatView, useSessionState
- UI/interactions: AccountMapCanvas, Dialog (useEscapeKey), ChatSettingsPanel,
  useAcpSession, useStreamingReveal
- Workspace: useWorkspaceCore (wsUrl derivation via useMemo)

Tests:
- Add useMediaQuery, useEscapeKey, useClickOutside hook tests
- Fix matchMedia mock in test setup for useSyncExternalStore
- Fix ThemeContext tests for useMediaQuery subscription model
- Fix useIsStandalone test for useSyncExternalStore snapshot pattern
- Fix error-list test mock to include useMediaQuery export

Reverted:
- OnboardingContext refactor (broke overlay auto-open behavior)
- DeploymentSettings cancellation (broke promise chain in tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Auto-committed by SAM on agent completion.
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@codspeed-hq

codspeed-hq Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing sam/implement-react-useeffect-audit-01kvz4 (165e0c5) with main (8c6f3ba)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant