Skip to content
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

Children of option tags flattened when select has value #11602

Closed
jorrit opened this issue Nov 20, 2017 · 15 comments
Closed

Children of option tags flattened when select has value #11602

jorrit opened this issue Nov 20, 2017 · 15 comments

Comments

@jorrit
Copy link
Contributor

jorrit commented Nov 20, 2017

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
When the following is rendered to string using ReactDOM:

<select value=""><option>a ({`b`})</option></select>

I get

<select data-reactroot=""><option>a (b)</option></select>

When hydrating the above code, I get this warning:

Warning: Text content did not match. Server: "a (b)" Client: "a ("

Fiddle: https://jsfiddle.net/z1q0azjL/1/

What is the expected behavior?

I should get:

<select data-reactroot=""><option>a (<!-- -->b<!-- -->)</option></select>

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

16.1.1

This has something to do with flattenOptionChildren in ReactPartialRenderer.js.

PS:
When browsing ReactPartialRenderer.js, I found this code:

        props = Object.assign(
          {
            selected: undefined,
            children: undefined,
          },
          props,
          {
            selected: selected,
            children: optionChildren,
          },
        );

What is the point of those undefined props when they are overwritten later on?

@gaearon
Copy link
Collaborator

gaearon commented Nov 20, 2017

Would you mind contributing a (failing) test to ReactDOMServerIntegration-test that verifies this case?

@jorrit
Copy link
Contributor Author

jorrit commented Nov 20, 2017

Sure, hopefully tomorrow (CET)!

@gaearon
Copy link
Collaborator

gaearon commented Jan 5, 2018

Do you want to work on a fix?

What is the point of those undefined props when they are overwritten later on?

That ensures objects have the same shape which helps performance.

@jorrit
Copy link
Contributor Author

jorrit commented Jan 6, 2018

Of course I tried, but I failed on the following point: currently the code concats the strings and leaves out any other children of <option> tags, in effect babysitting the developer a bit. When the child of an option tag is a single string a special code path is followed that isn't followed when the child is an array of strings. I could not get some client tests in react-dom working because of this.

I can push the changes I've made so far to #11911 and maybe you or another experienced dev can guide me to additional changes necessary?

@jorrit
Copy link
Contributor Author

jorrit commented Jan 6, 2018

BTW: thanks for the performance explanation.

@gaearon
Copy link
Collaborator

gaearon commented Jan 6, 2018

If you have some work in progress, send a PR and we can try to take it from there.

@jorrit
Copy link
Contributor Author

jorrit commented Jan 6, 2018

Done, thanks!

@t4deu
Copy link

t4deu commented Jan 20, 2018

Hi, the issue seems to be unassigned, can I take this one, I would love to help!!!

@jorrit
Copy link
Contributor Author

jorrit commented Jan 20, 2018

There is some progress by me in #11911, as far as I am concerned you're welcome to fork it and continue in a PR of your own. I hope you get it working properly!

@t4deu
Copy link

t4deu commented Jan 20, 2018

Great! I will do it, thanks

t4deu added a commit to t4deu/react that referenced this issue Jan 24, 2018
Avoid overwrite options children nodes when setting the selected option.
t4deu added a commit to t4deu/react that referenced this issue Jan 24, 2018
Avoid overwrite options children nodes when setting the selected option.
@t4deu
Copy link

t4deu commented Jan 24, 2018

Hello, I just sent a PR with the fix.

Apparently, it is caused by a regression introduced during the integration of Fiber.

The renderDOM method from ReactPartialRenderer was overwriting the children nodes from options, when setting the "selected" option, resulting in the bug.

As can be seen here, the previous version of the same feature only set the selected prop.

Since the bug was not related with flattenChildren, flattenOptionChildren or getHostProps that where removed/altered on the previous PR, I was unable to fork from it.

@jorrit
Copy link
Contributor Author

jorrit commented Jan 24, 2018

Thanks! Are my faling testcases from #11623 (I accidently referenced #11911 twice above when I actually meant #11623) working with your PR?

@t4deu
Copy link

t4deu commented Jan 24, 2018

Yes, but I needed to update the tests, the clientRenderOnServerString conditional is the same as serverRender and streamRender, so there was no need of an extra block.
The ReactDOMServerIntegrationForms-test seemed to be a better place, since it's where the tests for inputs, textareas and selects are, also updated the clientCleanRender test because only returns one text node.

Besides that also tested using the fiddle you provided and an SSR sample project that I created to reproduce the warning error and confirm that the issue is resolved.

t4deu added a commit to t4deu/react that referenced this issue Jan 24, 2018
Avoid overwrite options children nodes when setting the selected option.
@jorrit
Copy link
Contributor Author

jorrit commented Jan 24, 2018

Thanks a lot!

@gaearon
Copy link
Collaborator

gaearon commented Aug 2, 2018

This appears fixed by #13261.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants