Skip all special props when setting attributes on web components
Dan Abramov committed
Mar 16, 2016 at 21:10 UTC
c395c0977f458b7697787fc514041d70330965dd
2 files changed
+54
-14
src/renderers/dom/shared/ReactDOMComponent.js
+13
-9
@@ -53,9 +53,14 @@ var registrationNameModules = EventPluginRegistry.registrationNameModules;
53
// For quickly matching children type, to test if can be treated as content.
54
var CONTENT_TYPES = {'string': true, 'number': true};
55
56
-var CHILDREN = keyOf({children: null});
56
var STYLE = keyOf({style: null});
57
var HTML = keyOf({__html: null});
58
+var RESERVED_PROPS = {
59
+ children: null,
60
+ dangerouslySetInnerHTML: null,
61
+ suppressContentEditableWarning: null,
62
+};
63
+
64
65
function getDeclarationErrorAddendum(internalInstance) {
66
if (internalInstance) {
@@ -635,7 +640,7 @@ ReactDOMComponent.Mixin = {
640
}
641
var markup = null;
642
if (this._tag != null && isCustomComponent(this._tag, props)) {
638
- if (propKey !== CHILDREN) {
643
+ if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
644
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);
645
}
646
} else {
@@ -907,14 +912,13 @@ ReactDOMComponent.Mixin = {
912
deleteListener(this, propKey);
913
}
914
} else if (isCustomComponent(this._tag, nextProps)) {
910
- if (propKey === CHILDREN) {
911
- nextProp = null;
915
+ if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
916
+ DOMPropertyOperations.setValueForAttribute(
917
+ getNode(this),
918
+ propKey,
919
+ nextProp
920
+ );
921
}
913
- DOMPropertyOperations.setValueForAttribute(
914
- getNode(this),
915
- propKey,
916
- nextProp
917
- );
922
} else if (
923
DOMProperty.properties[propKey] ||
924
DOMProperty.isCustomAttribute(propKey)) {
src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js
+41
-5
@@ -236,16 +236,52 @@ describe('ReactDOMComponent', function() {
236
expect(stubStyle.display).toEqual('');
237
});
238
239
- it('should skip child object attribute on web components', function() {
239
+ it('should skip reserved props on web components', function() {
240
var container = document.createElement('div');
241
242
- // Test initial render to null
243
- ReactDOM.render(<my-component children={['foo']} />, container);
242
+ ReactDOM.render(
243
+ <my-component
244
+ children={['foo']}
245
+ suppressContentEditableWarning={true}
246
+ />,
247
+ container
248
+ );
249
expect(container.firstChild.hasAttribute('children')).toBe(false);
250
+ expect(
251
+ container.firstChild.hasAttribute('suppressContentEditableWarning')
252
+ ).toBe(false);
253
246
- // Test updates to null
247
- ReactDOM.render(<my-component children={['foo']} />, container);
254
+ ReactDOM.render(
255
+ <my-component
256
+ children={['bar']}
257
+ suppressContentEditableWarning={false}
258
+ />,
259
+ container
260
+ );
261
expect(container.firstChild.hasAttribute('children')).toBe(false);
262
+ expect(
263
+ container.firstChild.hasAttribute('suppressContentEditableWarning')
264
+ ).toBe(false);
265
+ });
266
+
267
+ it('should skip dangerouslySetInnerHTML on web components', function() {
268
+ var container = document.createElement('div');
269
+
270
+ ReactDOM.render(
271
+ <my-component dangerouslySetInnerHTML={{__html: 'hi'}} />,
272
+ container
273
+ );
274
+ expect(
275
+ container.firstChild.hasAttribute('dangerouslySetInnerHTML')
276
+ ).toBe(false);
277
+
278
+ ReactDOM.render(
279
+ <my-component dangerouslySetInnerHTML={{__html: 'bye'}} />,
280
+ container
281
+ );
282
+ expect(
283
+ container.firstChild.hasAttribute('dangerouslySetInnerHTML')
284
+ ).toBe(false);
285
});
286
287
it('should remove attributes', function() {