diff --git a/packages/react-dom/src/__tests__/ReactStatelessComponent-test.js b/packages/react-dom/src/__tests__/ReactStatelessComponent-test.js index 2ef98484f5e2d..aa13b58de8bce 100644 --- a/packages/react-dom/src/__tests__/ReactStatelessComponent-test.js +++ b/packages/react-dom/src/__tests__/ReactStatelessComponent-test.js @@ -98,6 +98,22 @@ describe('ReactStatelessComponent', () => { expect(el.textContent).toBe('mest'); }); + it('should warn for getDerivedStateFromProps on a functional component', () => { + function StatelessComponentWithChildContext() { + return null; + } + StatelessComponentWithChildContext.getDerivedStateFromProps = function() {}; + + const container = document.createElement('div'); + + expect(() => + ReactDOM.render(, container), + ).toWarnDev( + 'StatelessComponentWithChildContext: Stateless ' + + 'functional components do not support getDerivedStateFromProps.', + ); + }); + it('should warn for childContextTypes on a functional component', () => { function StatelessComponentWithChildContext(props) { return
{props.name}
; diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index f2c058d11a194..a92d19523c1ee 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -60,12 +60,14 @@ import { import {NoWork, Never} from './ReactFiberExpirationTime'; import {AsyncUpdates} from './ReactTypeOfInternalContext'; -let warnedAboutStatelessRefs; let didWarnAboutBadClass; +let didWarnAboutGetDerivedStateOnFunctionalComponent; +let didWarnAboutStatelessRefs; if (__DEV__) { - warnedAboutStatelessRefs = {}; didWarnAboutBadClass = {}; + didWarnAboutGetDerivedStateOnFunctionalComponent = {}; + didWarnAboutStatelessRefs = {}; } export default function( @@ -518,8 +520,8 @@ export default function( if (debugSource) { warningKey = debugSource.fileName + ':' + debugSource.lineNumber; } - if (!warnedAboutStatelessRefs[warningKey]) { - warnedAboutStatelessRefs[warningKey] = true; + if (!didWarnAboutStatelessRefs[warningKey]) { + didWarnAboutStatelessRefs[warningKey] = true; warning( false, 'Stateless function components cannot be given refs. ' + @@ -529,6 +531,23 @@ export default function( ); } } + + if (typeof fn.getDerivedStateFromProps === 'function') { + const componentName = getComponentName(workInProgress) || 'Unknown'; + + if ( + !didWarnAboutGetDerivedStateOnFunctionalComponent[componentName] + ) { + warning( + false, + '%s: Stateless functional components do not support getDerivedStateFromProps.', + componentName, + ); + didWarnAboutGetDerivedStateOnFunctionalComponent[ + componentName + ] = true; + } + } } reconcileChildren(current, workInProgress, value); memoizeProps(workInProgress, props);