@samitouri / QOS-React / commits / aca4ccda35

ReactDOMComponent should throw error when provided children for void elements

Jon Hester committed Mar 10, 2015 at 23:47 UTC aca4ccda357824243fd1125d5c64a83028c30be8
2 files changed +51 -50
src/renderers/dom/shared/ReactDOMComponent.js
+11 -13
@@ -241,19 +241,17 @@ function assertValidProps(component, props) {
241 return;
242 }
243 // Note the use of `==` which checks for null or undefined.
244 - if (__DEV__) {
245 - if (voidElementTags[component._tag]) {
246 - warning(
247 - props.children == null && props.dangerouslySetInnerHTML == null,
248 - '%s is a void element tag and must not have `children` or ' +
249 - 'use `props.dangerouslySetInnerHTML`.%s',
250 - component._tag,
251 - component._currentElement._owner ?
252 - ' Check the render method of ' +
253 - component._currentElement._owner.getName() + '.' :
254 - ''
255 - );
256 - }
244 + if (voidElementTags[component._tag]) {
245 + invariant(
246 + props.children == null && props.dangerouslySetInnerHTML == null,
247 + '%s is a void element tag and must not have `children` or ' +
248 + 'use `props.dangerouslySetInnerHTML`.%s',
249 + component._tag,
250 + component._currentElement._owner ?
251 + ' Check the render method of ' +
252 + component._currentElement._owner.getName() + '.' :
253 + ''
254 + );
255 }
256 if (props.dangerouslySetInnerHTML != null) {
257 invariant(
src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js
+40 -37
@@ -571,43 +571,44 @@ describe('ReactDOMComponent', function() {
571 });
572
573 it('should warn against children for void elements', function() {
574 - spyOn(console, 'error');
575 -
574 var container = document.createElement('div');
575
578 - ReactDOM.render(<input>children</input>, container);
579 -
580 - expect(console.error.argsForCall.length).toBe(1);
581 - expect(console.error.argsForCall[0][0]).toContain('void element');
576 + expect(function() {
577 + ReactDOM.render(<input>children</input>, container);
578 + }).toThrow(
579 + 'input is a void element tag and must not have `children` or ' +
580 + 'use `props.dangerouslySetInnerHTML`.'
581 + );
582 });
583
584 it('should warn against dangerouslySetInnerHTML for void elements', function() {
585 - spyOn(console, 'error');
586 -
585 var container = document.createElement('div');
586
589 - ReactDOM.render(
590 - <input dangerouslySetInnerHTML={{__html: 'content'}} />,
591 - container
587 + expect(function() {
588 + ReactDOM.render(
589 + <input dangerouslySetInnerHTML={{__html: 'content'}} />,
590 + container
591 + );
592 + }).toThrow(
593 + 'input is a void element tag and must not have `children` or use ' +
594 + '`props.dangerouslySetInnerHTML`.'
595 );
593 -
594 - expect(console.error.argsForCall.length).toBe(1);
595 - expect(console.error.argsForCall[0][0]).toContain('void element');
596 });
597
598 it('should treat menuitem as a void element but still create the closing tag', function() {
599 - spyOn(console, 'error');
600 -
599 var container = document.createElement('div');
600
601 var returnedValue = ReactDOMServer.renderToString(<menu><menuitem /></menu>);
602
603 expect(returnedValue).toContain('</menuitem>');
604
607 - ReactDOM.render(<menu><menuitem>children</menuitem></menu>, container);
605 + expect(function() {
606 + ReactDOM.render(<menu><menuitem>children</menuitem></menu>, container);
607 + }).toThrow(
608 + 'menuitem is a void element tag and must not have `children` or use ' +
609 + '`props.dangerouslySetInnerHTML`.'
610 + );
611
609 - expect(console.error.argsForCall.length).toBe(1);
610 - expect(console.error.argsForCall[0][0]).toContain('void element');
612 });
613
614 it('should validate against multiple children props', function() {
@@ -725,17 +726,17 @@ describe('ReactDOMComponent', function() {
726 });
727
728 it('should warn for children on void elements', function() {
728 - spyOn(console, 'error');
729 var X = React.createClass({
730 render: function() {
731 return <input>moo</input>;
732 },
733 });
734 +
735 var container = document.createElement('div');
735 - ReactDOM.render(<X />, container);
736 - expect(console.error.argsForCall.length).toBe(1);
737 - expect(console.error.argsForCall[0][0]).toBe(
738 - 'Warning: input is a void element tag and must not have `children` ' +
736 + expect(function() {
737 + ReactDOM.render(<X />, container);
738 + }).toThrow(
739 + 'input is a void element tag and must not have `children` ' +
740 'or use `props.dangerouslySetInnerHTML`. Check the render method of X.'
741 );
742 });
@@ -749,26 +750,28 @@ describe('ReactDOMComponent', function() {
750 });
751
752 it('should warn against children for void elements', function() {
752 - spyOn(console, 'error');
753 -
753 ReactDOM.render(<input />, container);
755 - ReactDOM.render(<input>children</input>, container);
754
757 - expect(console.error.argsForCall.length).toBe(1);
758 - expect(console.error.argsForCall[0][0]).toContain('void element');
755 + expect(function() {
756 + ReactDOM.render(<input>children</input>, container);
757 + }).toThrow(
758 + 'input is a void element tag and must not have `children` or use ' +
759 + '`props.dangerouslySetInnerHTML`.'
760 + );
761 });
762
763 it('should warn against dangerouslySetInnerHTML for void elements', function() {
762 - spyOn(console, 'error');
763 -
764 ReactDOM.render(<input />, container);
765 - ReactDOM.render(
766 - <input dangerouslySetInnerHTML={{__html: 'content'}} />,
767 - container
768 - );
765
770 - expect(console.error.argsForCall.length).toBe(1);
771 - expect(console.error.argsForCall[0][0]).toContain('void element');
766 + expect(function() {
767 + ReactDOM.render(
768 + <input dangerouslySetInnerHTML={{__html: 'content'}} />,
769 + container
770 + );
771 + }).toThrow(
772 + 'input is a void element tag and must not have `children` or use ' +
773 + '`props.dangerouslySetInnerHTML`.'
774 + );
775 });
776
777 it('should validate against multiple children props', function() {