Warn if class has a render() method but doesn't extend React.Component (#11168)
Warn if class has a render() method but doesn't extend React.Component
shawn wang committed
Oct 31, 2017 at 08:02 UTC
7f10fae4c18510f64d7cf07bcbf4a1742387f2e4
2 files changed
+31
packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
+20
@@ -326,6 +326,26 @@ describe('ReactCompositeComponent', () => {
326
expect(cbCalled).toBe(false);
327
});
328
329
+ it('should warn when rendering a class with a render method that does not extend React.Component', () => {
330
+ spyOn(console, 'error');
331
+ var container = document.createElement('div');
332
+ class ClassWithRenderNotExtended {
333
+ render() {
334
+ return <div />;
335
+ }
336
+ }
337
+ expectDev(console.error.calls.count()).toBe(0);
338
+ expect(() => {
339
+ ReactDOM.render(<ClassWithRenderNotExtended />, container);
340
+ }).toThrow(TypeError);
341
+ expectDev(console.error.calls.count()).toBe(1);
342
+ expectDev(console.error.calls.argsFor(0)[0]).toContain(
343
+ 'Warning: The <ClassWithRenderNotExtended /> component appears to have a render method, ' +
344
+ "but doesn't extend React.Component. This is likely to cause errors. " +
345
+ 'Change ClassWithRenderNotExtended to extend React.Component instead.',
346
+ );
347
+ });
348
+
349
it('should warn about `setState` in render', () => {
350
spyOn(console, 'error');
351
packages/react-reconciler/src/ReactFiberBeginWork.js
+11
@@ -39,6 +39,7 @@ var {
39
} = require('shared/ReactTypeOfSideEffect');
40
var {ReactCurrentOwner} = require('shared/ReactGlobalSharedState');
41
var invariant = require('fbjs/lib/invariant');
42
+var getComponentName = require('shared/getComponentName');
43
44
var ReactFiberClassComponent = require('./ReactFiberClassComponent');
45
var {
@@ -471,6 +472,16 @@ module.exports = function<T, P, I, TI, PI, C, CC, CX, PL>(
472
var value;
473
474
if (__DEV__) {
475
+ if (fn.prototype && typeof fn.prototype.render === 'function') {
476
+ const componentName = getComponentName(workInProgress);
477
+ warning(
478
+ false,
479
+ "The <%s /> component appears to have a render method, but doesn't extend React.Component. " +
480
+ 'This is likely to cause errors. Change %s to extend React.Component instead.',
481
+ componentName,
482
+ componentName,
483
+ );
484
+ }
485
ReactCurrentOwner.current = workInProgress;
486
value = fn(props, context);
487
} else {