Skip to content

ECHOES-1266 Harden React 19 ref handling to prevent callback-ref update loops (useForwardedRef, compose-refs, radio-group attach refs)#658

Merged
david-cho-lerat-sonarsource merged 1 commit intomainfrom
david/fix-react-19-useforwardref
Mar 24, 2026
Merged

ECHOES-1266 Harden React 19 ref handling to prevent callback-ref update loops (useForwardedRef, compose-refs, radio-group attach refs)#658
david-cho-lerat-sonarsource merged 1 commit intomainfrom
david/fix-react-19-useforwardref

Conversation

@david-cho-lerat-sonarsource
Copy link
Copy Markdown
Contributor

No description provided.

@sonar-review-alpha
Copy link
Copy Markdown

sonar-review-alpha Bot commented Mar 24, 2026

Summary

Hardens ref handling to prevent callback-ref update loops that cause "maximum update depth exceeded" errors in React 19. Implements three complementary fixes: (1) patches @radix-ui/react-compose-refs to skip calling function refs with null, breaking the detach/reattach feedback loop, (2) patches @radix-ui/react-radio-group's Radio component to use useRef instead of useState for button tracking, eliminating callback-ref-driven re-renders, and (3) updates useForwardedRef and useForwardedRefWithState helpers to guard against null calls and duplicate updates.

What reviewers should know

The problem: React 19's stricter ref semantics cause patterns like useState + callback-ref setters to loop—the callback triggers a state update, which re-renders and reattaches the ref, calling the callback again. Start with src/common/helpers/useForwardedRef.ts to see the internal pattern being fixed (guards on function refs, useCallback memoization, duplicate-update prevention). Then review the two patches in .yarn/patches/ to understand how they apply the same pattern to Radix dependencies. The radio-group patch is the most significant visual change (useState → useRef swap). package.json.md documents why each patch exists—review it to confirm you understand the trade-offs (these are upstream code patches, not local workarounds, so they'll need maintenance if radix updates).


  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 24, 2026

Deploy Preview for echoes-react ready!

Name Link
🔨 Latest commit 353c3d9
🔍 Latest deploy log https://app.netlify.com/projects/echoes-react/deploys/69c2956eed27780008b6f340
😎 Deploy Preview https://deploy-preview-658--echoes-react.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title Fix React 19 ref callback loops in useForwardedRef helpers ECHOES-1266 Fix React 19 ref callback loops in useForwardedRef helpers Mar 24, 2026
@hashicorp-vault-sonar-prod
Copy link
Copy Markdown

hashicorp-vault-sonar-prod Bot commented Mar 24, 2026

ECHOES-1266

@david-cho-lerat-sonarsource david-cho-lerat-sonarsource force-pushed the david/fix-react-19-useforwardref branch 7 times, most recently from b78a3f7 to 9817058 Compare March 24, 2026 09:18
@david-cho-lerat-sonarsource david-cho-lerat-sonarsource changed the title ECHOES-1266 Fix React 19 ref callback loops in useForwardedRef helpers ECHOES-1266 Harden React 19 ref handling to prevent callback-ref update loops (useForwardedRef, compose-refs, radio-group attach refs) Mar 24, 2026
Copy link
Copy Markdown
Contributor

@jeremy-davis-sonarsource jeremy-davis-sonarsource left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment thread package.json
Comment thread package.json
Comment thread src/components/layout/sidebar-navigation/__tests__/SidebarNavigationItem-test.tsx Outdated
…te loops (useForwardedRef, compose-refs, radio-group attach refs)
@david-cho-lerat-sonarsource david-cho-lerat-sonarsource force-pushed the david/fix-react-19-useforwardref branch from f16bd44 to 353c3d9 Compare March 24, 2026 13:45
@sonarqube-next
Copy link
Copy Markdown

@david-cho-lerat-sonarsource david-cho-lerat-sonarsource merged commit 4d4c591 into main Mar 24, 2026
7 of 8 checks passed
@david-cho-lerat-sonarsource david-cho-lerat-sonarsource deleted the david/fix-react-19-useforwardref branch March 24, 2026 13:49
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