-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Fixes children when using dangerouslySetInnerHtml in a selected <option> #13078
Conversation
This fixes an inadvertent cast of undefined children to an empty string when creating an option tag that will be selected: ``` <select defaultValue="test"> <option value='test' dangerouslySetInnerHTML={{ __html: '‏ test'}} /> </select> ``` This causes an invariant error because both children and dangerouslySetInnerHTML are set.
Do you mind adding a test to one of |
const optionChildren = flattenOptionChildren(props.children); | ||
const optionChildren = Array.isArray(props.children) | ||
? flattenOptionChildren(props.children) | ||
: props.children; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for an Array isn't sufficient since React supports using iterables as children. Instead, can we invert the logic so that it checks for undefined
?
const optionChildren = props.children === undefined
? props.children
: flattenOptionChildren(props.children)
Alternatively we could just add that check to flattenOptionChildren
directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're totally right. I'm not sure all of the possible cases here. I do know that null
is also possible in this case. Would null
and undefined
checks be sufficient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If children was null
then the user must have explicitly rendered with null
as a child. In that case we still want to throw because that counts as using children. We just want to handle the case where there are no children at all, so just checking undefined
is sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case we still want to throw because that counts as using children
Do we? On the client we only fire the invariant with == null
check so neither null
nor undefined
counts:
react/src/renderers/dom/shared/ReactDOMComponent.js
Lines 161 to 164 in 571a920
invariant( | |
props.children == null, | |
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.', | |
); |
Server logic should be the same, shouldn't it? Or am I missing something?
We should have a test for this too I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we threw for null
. You're right, server logic should be the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make sure we don't throw for null
, and modify the integration test to include this scenario
Updated to check for |
I'd prefer copy pasting since there's already too much indirection in that file. |
Also, can you make a single test with multiple options, each option having a different falsy value (e.g. |
Yes, for some reason I thought that the option had to be selected, but if any of them are selected they are all run through this code path. So I will combine the tests into one. We would expect |
Yeah, a separate test for error consistency would be good. (I think we have a few tests in that suite that show how to assert failures.) |
Looks like |
Thank you! |
This fixes an inadvertent cast of undefined children to an empty string when creating an option tag that will be selected:
This causes an invariant error because both children and dangerouslySetInnerHTML are set.
What is the current behavior?
What is the expected behavior?
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.4.1 using node 8. This worked in 15.x.