fix(select): prevent spurious onValueChange on controlled value updates #3759
+99
−1
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.
Summary
Fixes spurious
onValueChangecalls with empty string when controlled Select value is updated externally inside a form.Problem
When using Select as a controlled component inside a
<form>and updating thevalueprop externally (e.g., via React Hook Form'sreset()),onValueChangewas being called with an empty string'', which would overwrite the valid controlled value.Reproduction steps:
<form>valueprop externally (e.g.,setValue('apple'))onValueChangeis spuriously called with''after the valid value updateRoot Cause
The
SelectBubbleInputcomponent (hidden native select for form integration) has anonChangehandler that receives events from the internalBubbleSelectuseEffect which dispatches synthetic change events for form syncing. When the native select element hasn't fully updated with the new value,event.target.valuereturns empty string, triggering the spurious callback.Solution
Guard the internal
onChangehandler to prevent empty value updates when a valid controlled value already exists:This ensures
onValueChangeis only called for:Testing
ControlledInFormExternalUpdatedemonstrating the fixChangeset
Included patch changeset for
@radix-ui/react-selectFixes #3135, #3249, #3693