Skip to content

Commit a270e03

Browse files
committed
Ignore and warn about non-string is attribute
1 parent fbcced1 commit a270e03

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

src/renderers/dom/fiber/ReactDOMFiberComponent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ var ReactDOMFiberComponent = {
326326
// This is guaranteed to yield a script element.
327327
var firstChild = ((div.firstChild: any): HTMLScriptElement);
328328
domElement = div.removeChild(firstChild);
329-
} else if (props.is) {
329+
} else if (typeof props.is === 'string') {
330330
// $FlowIssue `createElement` should be updated for Web Components
331331
domElement = ownerDocument.createElement(type, {is: props.is});
332332
} else {

src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,12 +635,24 @@ describe('ReactDOMComponent', () => {
635635
expect(nodeValueSetter.mock.calls.length).toBe(3);
636636
});
637637

638-
it('should ignore attribute whitelist for elements with the "is: attribute', () => {
638+
it('should ignore attribute whitelist for elements with the "is" attribute', () => {
639639
var container = document.createElement('div');
640640
ReactDOM.render(<button is="test" cowabunga="chevynova" />, container);
641641
expect(container.firstChild.hasAttribute('cowabunga')).toBe(true);
642642
});
643643

644+
it('should warn about non-string "is" attribute', () => {
645+
spyOn(console, 'error');
646+
var container = document.createElement('div');
647+
ReactDOM.render(<button is={function() {}} />, container);
648+
649+
expectDev(console.error.calls.count()).toBe(1);
650+
expectDev(console.error.calls.argsFor(0)[0]).toContain(
651+
'Received a `function` for string attribute `is`. If this is expected, cast ' +
652+
'the value to a string.',
653+
);
654+
});
655+
644656
it('should not update when switching between null/undefined', () => {
645657
var container = document.createElement('div');
646658
var node = ReactDOM.render(<div />, container);

src/renderers/dom/shared/hooks/ReactDOMUnknownPropertyHook.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,23 @@ if (__DEV__) {
105105
return true;
106106
}
107107

108+
if (
109+
lowerCasedName === 'is' &&
110+
value !== null &&
111+
value !== undefined &&
112+
typeof value !== 'string'
113+
) {
114+
warning(
115+
false,
116+
'Received a `%s` for string attribute `is`. If this is expected, cast ' +
117+
'the value to a string.%s',
118+
typeof value,
119+
getStackAddendum(debugID),
120+
);
121+
warnedProperties[name] = true;
122+
return true;
123+
}
124+
108125
if (typeof value === 'number' && isNaN(value)) {
109126
warning(
110127
false,

src/renderers/dom/shared/utils/isCustomComponent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var DOMNamespaces = require('DOMNamespaces');
1515
var HTML_NAMESPACE = DOMNamespaces.Namespaces.html;
1616

1717
function isCustomComponent(tagName, props, namespace) {
18-
if (tagName.indexOf('-') >= 0 || props.is != null) {
18+
if (tagName.indexOf('-') >= 0 || typeof props.is === 'string') {
1919
// TODO: We always have a namespace with fiber. Drop the first
2020
// check when Stack is removed.
2121
return namespace == null || namespace === HTML_NAMESPACE;

src/renderers/dom/stack/client/ReactDOMComponent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ ReactDOMComponent.Mixin = {
552552
var div = ownerDocument.createElement('div');
553553
div.innerHTML = `<${type}></${type}>`;
554554
el = div.removeChild(div.firstChild);
555-
} else if (props.is) {
555+
} else if (typeof props.is === 'string') {
556556
el = ownerDocument.createElement(type, {is: props.is});
557557
} else {
558558
// Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.

0 commit comments

Comments
 (0)