-
Notifications
You must be signed in to change notification settings - Fork 47.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Regression: React 16 automatically marks first item of a mutliple select as checked #12200
Comments
cc @aweary |
The change was made specifically for the single select since that's what the specced behavior is supposed to be. It seems like this behavior is only specified when the ref: https://html.spec.whatwg.org/multipage/form-elements.html#concept-select-size |
jsfiddle showing non-react behavior: https://jsfiddle.net/wvr6f6x3/
Same in Chrome, Safari, and FF (random bonus there is like 7 year old bug in webkit where looks like the logic is, "only select the first option when it's not displayed like a listbox" |
The last time we touched this select logic was in #11057, which doesn't actually affect the behavior we're seeing here ( The reason we see this regression is because the order of operations between when attributes are set and children are appended has changed. In React 15, attributes were set on an element before the children were appended. This means that In React 16, children are appended before attributes are set on the parent. So all the react/packages/react-reconciler/src/ReactFiberCompleteWork.js Lines 507 to 519 in 467b103
This exposes some nuanced behavior around how option elements work: if you append a child to a So what happens in React 16 is that we append all the options to a select element that it assumes is a single select, and we see the spec defined behavior @jquense mentioned. Here's an example reproducing this issue without React. You'll see that if you set |
The solution will likely be either:
The first option is probably the best one if it doesn't cause any other problems. The third option is probably the easiest, but more of a hacky solution. |
@aweary Do you mind if I take this on as my first issue? |
@GarethSmall go for it 👍 let us know if you have any questions, it's not the most straightforward are of the code base :P |
@jquense Thank you! I've got many, i'm looking through the tests now. If I have any afterwards, I'll be sure to ask. |
Continuing the discussion from #12240 I think it makes the most sense to ensure that all attributes are set before children are appended. I'll try and comb through the spec for more append behavior that forks based on parent attributes, but my gut tells me The problem with just re-ordering the reconciler methods is that this might not make sense for other renderers like React Native. Maybe @acdlite or @bvaughn have some insights there? Maybe we could put the |
From what it looks like we're doing two things in setInitialProperties, we're setting the initial properties and we're "handling" events. Is it fair to say these two processes should be separated? Also, can we confirm this is an issue in other areas? I'm going to do some tests in fiddle and see if I can cause any issues from this order. |
Another thing to note is if we set the properties before we append the children we run into other issues. For example: We have a defaultValue property we set properties > append all children our defaultValue won't be set. I think as you suggested manually fixing this in |
Do you want to request a feature or report a bug?
Bug - Regression
What is the current behavior?
In react 16 when creating a
<select multiple>
the first child<option>
is automatically getting marked as selected. In React 16 there does not seem to be a way to specify no<option>
gets selected by defaulthttps://codesandbox.io/s/moxm2on3z9
What is the expected behavior?
In React 15 unless you marked an option to be selected
<option selected>
no options were selected by default.https://codesandbox.io/s/ll11z5wqzl
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Versions effected include
react^16.2
, this worked inreact^0.13
andreact^15
. This bug is reproducible in chrome 64 and Firefox 58.The hacky workaround I found to get around the first option getting selected is to inject a
<option style={{display: 'none'}} />
as the first child of the multiselect.The text was updated successfully, but these errors were encountered: