Added check to deduplicate function type warning calls on each compon… (#11120)
* Added check to deduplicate function type warning calls on each component type * Added test to check that 'function type as React child' warning is deduplicated correctly by component type * Ran prettier on added code * Modified test checking deduplication of 'Functions are not valid as a React child' warning so it will check against rerendering component now
andreysaleba committed
Oct 6, 2017 at 23:40 UTC
12144517f9bd09f44ae13a64c5a3522c982ed354
2 files changed
+49
src/renderers/__tests__/ReactComponent-test.js
+37
@@ -542,5 +542,42 @@ describe('ReactComponent', () => {
542
expect(container.innerHTML).toBe('Hello');
543
expectDev(console.error.calls.count()).toBe(0);
544
});
545
+
546
+ it('deduplicates function type warnings based on component type', () => {
547
+ spyOn(console, 'error');
548
+ class Foo extends React.PureComponent {
549
+ constructor() {
550
+ super();
551
+ this.state = {type: 'mushrooms'};
552
+ }
553
+ render() {
554
+ return (
555
+ <div>
556
+ {Foo}{Foo}
557
+ <span>{Foo}{Foo}</span>
558
+ </div>
559
+ );
560
+ }
561
+ }
562
+ var container = document.createElement('div');
563
+ var component = ReactDOM.render(<Foo />, container);
564
+ component.setState({type: 'portobello mushrooms'});
565
+ expectDev(console.error.calls.count()).toBe(2);
566
+ expectDev(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
567
+ 'Warning: Functions are not valid as a React child. This may happen if ' +
568
+ 'you return a Component instead of <Component /> from render. ' +
569
+ 'Or maybe you meant to call this function rather than return it.\n' +
570
+ ' in div (at **)\n' +
571
+ ' in Foo (at **)',
572
+ );
573
+ expectDev(normalizeCodeLocInfo(console.error.calls.argsFor(1)[0])).toBe(
574
+ 'Warning: Functions are not valid as a React child. This may happen if ' +
575
+ 'you return a Component instead of <Component /> from render. ' +
576
+ 'Or maybe you meant to call this function rather than return it.\n' +
577
+ ' in span (at **)\n' +
578
+ ' in div (at **)\n' +
579
+ ' in Foo (at **)',
580
+ );
581
+ });
582
});
583
});
src/renderers/shared/fiber/ReactChildFiber.js
+12
@@ -35,6 +35,7 @@ if (__DEV__) {
35
* updates.
36
*/
37
var ownerHasKeyUseWarning = {};
38
+ var ownerHasFunctionTypeWarning = {};
39
40
var warnForMissingKey = (child: mixed) => {
41
if (child === null || typeof child !== 'object') {
@@ -192,6 +193,17 @@ function throwOnInvalidObjectType(returnFiber: Fiber, newChild: Object) {
193
}
194
195
function warnOnFunctionType() {
196
+ const currentComponentErrorInfo =
197
+ 'Functions are not valid as a React child. This may happen if ' +
198
+ 'you return a Component instead of <Component /> from render. ' +
199
+ 'Or maybe you meant to call this function rather than return it.' +
200
+ (getCurrentFiberStackAddendum() || '');
201
+
202
+ if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
203
+ return;
204
+ }
205
+ ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
206
+
207
warning(
208
false,
209
'Functions are not valid as a React child. This may happen if ' +