From aca4ccda357824243fd1125d5c64a83028c30be8 Mon Sep 17 00:00:00 2001 From: Jon Hester Date: Tue, 10 Mar 2015 23:47:26 -0400 Subject: [PATCH] ReactDOMComponent should throw error when provided children for void elements --- src/renderers/dom/shared/ReactDOMComponent.js | 24 +++--- .../__tests__/ReactDOMComponent-test.js | 77 ++++++++++--------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/renderers/dom/shared/ReactDOMComponent.js b/src/renderers/dom/shared/ReactDOMComponent.js index 97f6e2b1bb1f0..98540ec088828 100644 --- a/src/renderers/dom/shared/ReactDOMComponent.js +++ b/src/renderers/dom/shared/ReactDOMComponent.js @@ -241,19 +241,17 @@ function assertValidProps(component, props) { return; } // Note the use of `==` which checks for null or undefined. - if (__DEV__) { - if (voidElementTags[component._tag]) { - warning( - props.children == null && props.dangerouslySetInnerHTML == null, - '%s is a void element tag and must not have `children` or ' + - 'use `props.dangerouslySetInnerHTML`.%s', - component._tag, - component._currentElement._owner ? - ' Check the render method of ' + - component._currentElement._owner.getName() + '.' : - '' - ); - } + if (voidElementTags[component._tag]) { + invariant( + props.children == null && props.dangerouslySetInnerHTML == null, + '%s is a void element tag and must not have `children` or ' + + 'use `props.dangerouslySetInnerHTML`.%s', + component._tag, + component._currentElement._owner ? + ' Check the render method of ' + + component._currentElement._owner.getName() + '.' : + '' + ); } if (props.dangerouslySetInnerHTML != null) { invariant( diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js index 9f6528c35b40b..a4087cedf87eb 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js @@ -571,43 +571,44 @@ describe('ReactDOMComponent', function() { }); it('should warn against children for void elements', function() { - spyOn(console, 'error'); - var container = document.createElement('div'); - ReactDOM.render(children, container); - - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('void element'); + expect(function() { + ReactDOM.render(children, container); + }).toThrow( + 'input is a void element tag and must not have `children` or ' + + 'use `props.dangerouslySetInnerHTML`.' + ); }); it('should warn against dangerouslySetInnerHTML for void elements', function() { - spyOn(console, 'error'); - var container = document.createElement('div'); - ReactDOM.render( - , - container + expect(function() { + ReactDOM.render( + , + container + ); + }).toThrow( + 'input is a void element tag and must not have `children` or use ' + + '`props.dangerouslySetInnerHTML`.' ); - - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('void element'); }); it('should treat menuitem as a void element but still create the closing tag', function() { - spyOn(console, 'error'); - var container = document.createElement('div'); var returnedValue = ReactDOMServer.renderToString(); expect(returnedValue).toContain(''); - ReactDOM.render(children, container); + expect(function() { + ReactDOM.render(children, container); + }).toThrow( + 'menuitem is a void element tag and must not have `children` or use ' + + '`props.dangerouslySetInnerHTML`.' + ); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('void element'); }); it('should validate against multiple children props', function() { @@ -725,17 +726,17 @@ describe('ReactDOMComponent', function() { }); it('should warn for children on void elements', function() { - spyOn(console, 'error'); var X = React.createClass({ render: function() { return moo; }, }); + var container = document.createElement('div'); - ReactDOM.render(, container); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toBe( - 'Warning: input is a void element tag and must not have `children` ' + + expect(function() { + ReactDOM.render(, container); + }).toThrow( + 'input is a void element tag and must not have `children` ' + 'or use `props.dangerouslySetInnerHTML`. Check the render method of X.' ); }); @@ -749,26 +750,28 @@ describe('ReactDOMComponent', function() { }); it('should warn against children for void elements', function() { - spyOn(console, 'error'); - ReactDOM.render(, container); - ReactDOM.render(children, container); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('void element'); + expect(function() { + ReactDOM.render(children, container); + }).toThrow( + 'input is a void element tag and must not have `children` or use ' + + '`props.dangerouslySetInnerHTML`.' + ); }); it('should warn against dangerouslySetInnerHTML for void elements', function() { - spyOn(console, 'error'); - ReactDOM.render(, container); - ReactDOM.render( - , - container - ); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('void element'); + expect(function() { + ReactDOM.render( + , + container + ); + }).toThrow( + 'input is a void element tag and must not have `children` or use ' + + '`props.dangerouslySetInnerHTML`.' + ); }); it('should validate against multiple children props', function() {