diff --git a/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js b/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js index 75f3e8060f384..56bd6c63aba24 100644 --- a/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js +++ b/packages/react-dom/src/__tests__/ReactCompositeComponent-test.js @@ -326,6 +326,26 @@ describe('ReactCompositeComponent', () => { expect(cbCalled).toBe(false); }); + it('should warn when rendering a class with a render method that does not extend React.Component', () => { + spyOn(console, 'error'); + var container = document.createElement('div'); + class ClassWithRenderNotExtended { + render() { + return
; + } + } + expectDev(console.error.calls.count()).toBe(0); + expect(() => { + ReactDOM.render(, container); + }).toThrow(TypeError); + expectDev(console.error.calls.count()).toBe(1); + expectDev(console.error.calls.argsFor(0)[0]).toContain( + 'Warning: The component appears to have a render method, ' + + "but doesn't extend React.Component. This is likely to cause errors. " + + 'Change ClassWithRenderNotExtended to extend React.Component instead.', + ); + }); + it('should warn about `setState` in render', () => { spyOn(console, 'error'); diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index efeb2a29f2801..868b7e244ab0c 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -39,6 +39,7 @@ var { } = require('shared/ReactTypeOfSideEffect'); var {ReactCurrentOwner} = require('shared/ReactGlobalSharedState'); var invariant = require('fbjs/lib/invariant'); +var getComponentName = require('shared/getComponentName'); var ReactFiberClassComponent = require('./ReactFiberClassComponent'); var { @@ -471,6 +472,16 @@ module.exports = function( var value; if (__DEV__) { + if (fn.prototype && typeof fn.prototype.render === 'function') { + const componentName = getComponentName(workInProgress); + warning( + false, + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + 'This is likely to cause errors. Change %s to extend React.Component instead.', + componentName, + componentName, + ); + } ReactCurrentOwner.current = workInProgress; value = fn(props, context); } else {