@@ -80,29 +80,38 @@ function updateOptions(
8080 if ( options [ i ] . selected !== selected ) {
8181 options [ i ] . selected = selected ;
8282 }
83- if ( selected && setDefaultSelected ) {
84- options [ i ] . defaultSelected = true ;
83+ if ( setDefaultSelected ) {
84+ options [ i ] . defaultSelected = selected ;
8585 }
8686 }
8787 } else {
8888 // Do not set `select.value` as exact behavior isn't consistent across all
8989 // browsers for all cases.
9090 const selectedValue = toString ( getToStringValue ( propValue ) ) ;
91- let defaultSelected = null ;
91+ // We use null as a signal that an option is explicitly selected.
92+ let defaultSelected : void | null | HTMLOptionElement = undefined ;
9293 for ( let i = 0 ; i < options . length ; i ++ ) {
93- if ( options [ i ] . value === selectedValue ) {
94+ const selected = options [ i ] . value === selectedValue ;
95+ if ( setDefaultSelected ) {
96+ options [ i ] . defaultSelected = selected ;
97+ }
98+ if ( selected ) {
9499 options [ i ] . selected = true ;
95- if ( setDefaultSelected ) {
96- options [ i ] . defaultSelected = true ;
100+ defaultSelected = null ;
101+ if ( ! setDefaultSelected ) {
102+ // We need to loop through all options when updating defaultSelected.
103+ // Otherwise multiple options may end up with defaultSelected=true
104+ // and resetting won't work properly.
105+ return ;
97106 }
98- return ;
99107 }
100- if ( defaultSelected === null && ! options [ i ] . disabled ) {
108+ if ( defaultSelected === undefined && ! options [ i ] . disabled ) {
101109 defaultSelected = options [ i ] ;
102110 }
103111 }
104- if ( defaultSelected !== null ) {
112+ if ( defaultSelected !== null && defaultSelected !== undefined ) {
105113 defaultSelected . selected = true ;
114+ defaultSelected . defaultSelected = true ;
106115 }
107116 }
108117}
@@ -152,7 +161,7 @@ export function initSelect(
152161 const node : HTMLSelectElement = ( element : any ) ;
153162 node . multiple = ! ! multiple ;
154163 if ( value != null ) {
155- updateOptions ( node , ! ! multiple , value , false ) ;
164+ updateOptions ( node , ! ! multiple , value , true ) ;
156165 } else if ( defaultValue != null ) {
157166 updateOptions ( node , ! ! multiple , defaultValue , true ) ;
158167 }
@@ -221,7 +230,7 @@ export function updateSelect(
221230 const node : HTMLSelectElement = ( element : any ) ;
222231
223232 if ( value != null ) {
224- updateOptions ( node , ! ! multiple , value , false ) ;
233+ updateOptions ( node , ! ! multiple , value , true ) ;
225234 } else if ( ! ! wasMultiple !== ! ! multiple ) {
226235 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
227236 if ( defaultValue != null ) {
@@ -238,6 +247,6 @@ export function restoreControlledSelectState(element: Element, props: Object) {
238247 const value = props . value ;
239248
240249 if ( value != null ) {
241- updateOptions ( node , ! ! props . multiple , value , false ) ;
250+ updateOptions ( node , ! ! props . multiple , value , true ) ;
242251 }
243252}
0 commit comments