-
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
Should not coerce children prop on custom elements to a string. Fixes #5088 #5093
Should not coerce children prop on custom elements to a string. Fixes #5088 #5093
Conversation
a703c37
to
ef85ba2
Compare
ef85ba2
to
530b7f7
Compare
Should we just treat children (and dangerouslySetInnerHTML) specially? It seems maybe-useful to cast other things to string. |
Yeah, that's what my original diff (jimfb@a703c37) did, but then I thought about it and most of the coercions were mistakes. There are situations where we might want to treat non-string values differently (for instance, a function property following the pattern onXXX might be treated as an event handler). Figured we could always relax the coercion requirement in the future, but for now requiring it to be a string/number seems like a reasonable restriction. If you still want it changed, let me know, I don't have a strong preference. |
Ping @spicyj. Have I convinced you that we should require all webcomponent props to be strings/numbers, and perhaps back off on this requirement later. Or would you prefer to go with the older diff (jimfb@a703c37). Or what's your thinking? |
Regardless, this is a breaking change so it should not be a patch level release. It can go into 0.15. |
@sebmarkbage Addresses a regression that we introduced; namely that we now set the |
Then we should do what @spicyj suggested and your original. JS has lots of coercion. It's just how the language works. Silently ignoring isn't necessarily better. It is probably worse here since it becomes a breaking change rather than an isolated patch of the regression. If you want to protect against it, use Flow or something like Restrict Mode on top. |
27cf905
to
0ae1fba
Compare
@jimfb updated the pull request. |
@spicyj @sebmarkbage PR updated; ready to merge? |
if (this._tag != null && isCustomComponent(this._tag, props)) { | ||
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); | ||
if (propKey != 'children' || typeof propValue === 'string' || typeof propValue === 'number') { |
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.
Plain string comparison is not closure compiler compatible.
We should ignore it even if it's a string/number.
Otherwise this won't work:
<custom-element>My Text Content</custom-element>
Also, could you add some tests that actually involve children like the issue that you're fixing.
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.
To get past the closure compiler issue you can use var CHILDREN = keyOf({children: null})
and then use that in place of the string literal.
That's the safest thing, though children
might actually be in the DOM externs.
0ae1fba
to
f12fd6b
Compare
@jimfb updated the pull request. |
if (this._tag != null && isCustomComponent(this._tag, props)) { | ||
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); | ||
if (propKey != CHILDREN || typeof propValue === 'string' || typeof propValue === 'number') { |
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.
!==
(looks like we might have relaxed that when switching to fbjs lint rules)
@spicyj's long line length detector is slipping…
@jimfb I'm going to do another 0.14.2 soon so if you can fix up the last few things we can probably get this in there. Although… I don't see history of when this got changed from 0.15 to 0.14.1, is it actually safe? |
f12fd6b
to
42211a9
Compare
Done. I rebased. This was a regression introduced in 0.14, so it should be safe. |
42211a9
to
3769cb3
Compare
@jimfb updated the pull request. |
Well, this doesn't quite bring us back to the same behavior of 0.13. So regression… sort of yes. But the changes here don't "fix" everything. I don't know what's right. I think there's also an argument to be made for explicit use of the React.renderToStaticMarkup(<my-component>5</my-component>)
React.renderToStaticMarkup(<my-component children={5}></my-component>)
React.renderToStaticMarkup(<my-component>{[5]}</my-component>)
// 0.13.3
'<my-component>5</my-component>'
'<my-component>5</my-component>'
'<my-component>5</my-component>'
0.14.1
'<my-component children="5">5</my-component>'
'<my-component children="5">5</my-component>'
'<my-component children="5">5</my-component>'
// With this
'<my-component children="5">5</my-component>'
'<my-component children="5">5</my-component>'
'<my-component>5</my-component>' As you can see, you've only changed that last one. Which is consistent with the "not coercing children" issue as filed. Maybe that's correct and I should shut up, it just seems weird. |
@zpao So the "correct" behavior, imo, is to have Sebastian wants (at least for now) us to drop the typeof checks, so I'll do that now. |
3769cb3
to
0595263
Compare
@@ -742,9 +743,11 @@ ReactDOMComponent.Mixin = { | |||
} | |||
propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this); | |||
} | |||
var markup = null; | |||
var markup = ''; |
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.
Why is this change needed?
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.
No idea. Presumably I wouldn't have made it if it wasn't necessary, but I don't see the reason for it and it passes unit tests as null so I'll go ahead and remove it.
0595263
to
86fc947
Compare
@jimfb updated the pull request. |
I think that it is likely that if we wanted to "standardize" the outline of a React Element, that other people might have opinion on this part of the structure. If it becomes necessary, I'd like to punt changing the React Element outline until that point. |
Should not coerce children prop on custom elements to a string. Fixes #5088
…coercion Should not coerce children prop on custom elements to a string. Fixes facebook#5088 (cherry picked from commit a2d26c8)
Should not coerce children prop (or any prop, really) on custom elements to a string. Fixes #5088