You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR extends our @radix-ui/react-compose-refs patch to prevent repeated callback-ref updates with the same DOM node.
We already patched setRef to ignore null callback invocations.
This PR adds a second guard in composeRefs to short-circuit when the incoming node is identical to the previous one.
Why
With React 19, callback refs can be invoked in patterns that trigger repeated updates even when the node identity does not change.
In Echoes usage paths (notably Select/Popover stacks), this can lead to render/update churn and, in some contexts, Maximum update depth exceeded.
What changed
In .yarn/patches/@radix-ui-react-compose-refs-npm-1.1.2-f0371f8267.patch:
Keep existing behavior: do not forward null to callback refs in setRef.
Add idempotency in composeRefs(...refs):
store previousNode
return early when node === previousNode
Scope
Patch-level change in a Radix dependency used by Echoes.
No public API changes in Echoes components.
Expected impact
Reduces unnecessary callback-ref executions.
Prevents ref-driven update loops in affected React 19 paths.
Should stabilize consumers seeing Maximum update depth exceeded from Echoes internals.
hashicorp-vault-sonar-prodbot
changed the title
Fix compose-refs repeated callback updates in React 19
ECHOES-1269 Fix compose-refs repeated callback updates in React 19
Mar 25, 2026
Adds an idempotency check to the composeRefs function in the patched Radix react-compose-refs library. When React 19 invokes the composed ref callback multiple times with the same DOM node, the patch now short-circuits instead of re-executing all ref assignments. This prevents unnecessary updates and update-depth errors in stacked components like Select/Popover. The fix maintains state across callback invocations using a closure variable (previousNode) to detect repeats.
What reviewers should know
The actual change is in .yarn/patches/@radix-ui-react-compose-refs-npm-1.1.2-f0371f8267.patch (lines 47–58 in the unified diff). Look for the previousNode closure variable and the identity check if (node === previousNode). The logic is: store the node on each call, bail early if it's identical to the previous one, otherwise proceed with setting all refs. Both the patch source and dist/index.mjs are updated in lockstep — the yarn.lock changes just reflect the recomputed hash. No behavioral change for cases where the node identity actually differs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR extends our
@radix-ui/react-compose-refspatch to prevent repeated callback-ref updates with the same DOM node.We already patched
setRefto ignorenullcallback invocations.This PR adds a second guard in
composeRefsto short-circuit when the incoming node is identical to the previous one.Why
With React 19, callback refs can be invoked in patterns that trigger repeated updates even when the node identity does not change.
In Echoes usage paths (notably Select/Popover stacks), this can lead to render/update churn and, in some contexts,
Maximum update depth exceeded.What changed
In
.yarn/patches/@radix-ui-react-compose-refs-npm-1.1.2-f0371f8267.patch:nullto callback refs insetRef.composeRefs(...refs):previousNodenode === previousNodeScope
Expected impact
Maximum update depth exceededfrom Echoes internals.