Skip to content

fix: remove render-phase React hazards - #883

Merged
Neonforge98 merged 1 commit into
developfrom
codex/react-compiler-cleanup
Aug 22, 2026
Merged

fix: remove render-phase React hazards#883
Neonforge98 merged 1 commit into
developfrom
codex/react-compiler-cleanup

Conversation

@Harry19081

Copy link
Copy Markdown
Member

Problem

Several React Compiler diagnostics were suppressing real render-phase hazards: Tooltip mutated a ref-backed holder during render, GitStatusProvider synchronized live refs during render, TeamRuntimePanel read wall-clock time during render, and Source Control used a render-mutated ref cache. Valid clone/ref forwarding, virtualizer, TanStack, and server-rendered test-probe suppressions also lacked enough context to distinguish false positives from bugs.

Solution

  • Compose Tooltip child refs in React callback-ref commits and ignore transient detach/reattach nulls for positioning, with a regression test for changing callback refs.
  • Synchronize Git WebSocket freshness refs in a layout effect, retaining one listener lifecycle instead of resubscribing on status writes.
  • Replace TeamRuntimePanel render-time Date.now reads with a minute-aligned, visibility-aware recursive timeout that pauses hidden and cleans up on unmount.
  • Replace the Source Control render-time ref cache with a complete primitive working-tree identity snapshot; unchanged status pings retain the derived array, while real path/status/staged/rename changes invalidate it.
  • Add precise reasons to intentional React Compiler suppressions for cloneElement ref forwarding, ref-capturing factories, TanStack imperative APIs, and test-only server-render probes.

Potential risks

Tooltip ref identity changes still follow React callback-ref semantics, but positioning state now ignores only the transient null and updates for a genuinely different DOM node. The runtime clock adds at most one timeout while the panel is mounted and visible; it removes the timer while hidden and during cleanup. The Source Control identity path serializes the same O(n) fields previously derived and compared on every status ping, and only parses/re-derives when the primitive key changes.

Verification

  • Changed-file ESLint with --report-unused-disable-directives: passed
  • pnpm typecheck: passed
  • Focused Vitest: 5 files, 31 tests passed
  • git diff --check: passed
  • Repository pre-commit gates: lint-staged, TypeScript, and staged-file checks passed

Performance verdict: lifecycle-safe and expected neutral-to-improved. No hidden-page timer remains, Git listener ownership/count is unchanged, Tooltip removes render-phase ref mutation without adding a subscription, and unchanged git-status pings no longer allocate a derived GitFile list before equality comparison.

@Neonforge98
Neonforge98 merged commit d245ab4 into develop Aug 22, 2026
3 checks passed
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.

2 participants