diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.js b/packages/react-reconciler/src/ReactFiberClassComponent.js
index 389dd4ca4fe..f6d8e192d4b 100644
--- a/packages/react-reconciler/src/ReactFiberClassComponent.js
+++ b/packages/react-reconciler/src/ReactFiberClassComponent.js
@@ -364,6 +364,22 @@ export default function(
name,
name,
);
+ const noInstanceGetDerivedStateFromProps =
+ typeof instance.getDerivedStateFromProps !== 'function';
+ warning(
+ noInstanceGetDerivedStateFromProps,
+ '%s: getDerivedStateFromProps() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.',
+ name,
+ );
+ const noInstanceGetDerivedStateFromCatch =
+ typeof instance.getDerivedStateFromCatch !== 'function';
+ warning(
+ noInstanceGetDerivedStateFromCatch,
+ '%s: getDerivedStateFromCatch() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.',
+ name,
+ );
const state = instance.state;
if (state && (typeof state !== 'object' || isArray(state))) {
warning(false, '%s.state: must be set to an object or null', name);
diff --git a/packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee b/packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
index 2f0fa46455c..892a96d0475 100644
--- a/packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
+++ b/packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
@@ -118,6 +118,28 @@ describe 'ReactCoffeeScriptClass', ->
test React.createElement(Foo, foo: 'foo'), 'DIV', 'foo bar'
undefined
+ it 'warns if getDerivedStateFromProps is not static', ->
+ class Foo extends React.Component
+ render: ->
+ div()
+ getDerivedStateFromProps: ->
+ {}
+ expect(->
+ ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
+ ).toWarnDev 'Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.',
+ undefined
+
+ it 'warns if getDerivedStateFromCatch is not static', ->
+ class Foo extends React.Component
+ render: ->
+ div()
+ getDerivedStateFromCatch: ->
+ {}
+ expect(->
+ ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
+ ).toWarnDev 'Foo: getDerivedStateFromCatch() is defined as an instance method and will be ignored. Instead, declare it as a static method.',
+ undefined
+
it 'warns if state not initialized before static getDerivedStateFromProps', ->
class Foo extends React.Component
render: ->
diff --git a/packages/react/src/__tests__/ReactES6Class-test.js b/packages/react/src/__tests__/ReactES6Class-test.js
index 793a5153f87..c48d7244a4c 100644
--- a/packages/react/src/__tests__/ReactES6Class-test.js
+++ b/packages/react/src/__tests__/ReactES6Class-test.js
@@ -128,6 +128,36 @@ describe('ReactES6Class', () => {
test(, 'DIV', 'foo bar');
});
+ it('warns if getDerivedStateFromProps is not static', () => {
+ class Foo extends React.Component {
+ getDerivedStateFromProps() {
+ return {};
+ }
+ render() {
+ return
;
+ }
+ }
+ expect(() => ReactDOM.render(, container)).toWarnDev(
+ 'Foo: getDerivedStateFromProps() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.',
+ );
+ });
+
+ it('warns if getDerivedStateFromCatch is not static', () => {
+ class Foo extends React.Component {
+ getDerivedStateFromCatch() {
+ return {};
+ }
+ render() {
+ return ;
+ }
+ }
+ expect(() => ReactDOM.render(, container)).toWarnDev(
+ 'Foo: getDerivedStateFromCatch() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.',
+ );
+ });
+
it('warns if state not initialized before static getDerivedStateFromProps', () => {
class Foo extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
diff --git a/packages/react/src/__tests__/ReactTypeScriptClass-test.ts b/packages/react/src/__tests__/ReactTypeScriptClass-test.ts
index 68313fd68da..b51b89cc254 100644
--- a/packages/react/src/__tests__/ReactTypeScriptClass-test.ts
+++ b/packages/react/src/__tests__/ReactTypeScriptClass-test.ts
@@ -378,6 +378,40 @@ describe('ReactTypeScriptClass', function() {
test(React.createElement(Foo, {foo: 'foo'}), 'DIV', 'foo bar');
});
+ it('warns if getDerivedStateFromProps is not static', function() {
+ class Foo extends React.Component {
+ getDerivedStateFromProps() {
+ return {};
+ }
+ render() {
+ return React.createElement('div', {});
+ }
+ }
+ expect(function() {
+ ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
+ }).toWarnDev(
+ 'Foo: getDerivedStateFromProps() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.'
+ );
+ });
+
+ it('warns if getDerivedStateFromCatch is not static', function() {
+ class Foo extends React.Component {
+ getDerivedStateFromCatch() {
+ return {};
+ }
+ render() {
+ return React.createElement('div');
+ }
+ }
+ expect(function() {
+ ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
+ }).toWarnDev(
+ 'Foo: getDerivedStateFromCatch() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.'
+ );
+ });
+
it('warns if state not initialized before static getDerivedStateFromProps', function() {
class Foo extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
diff --git a/packages/react/src/__tests__/createReactClassIntegration-test.js b/packages/react/src/__tests__/createReactClassIntegration-test.js
index c567b4fd853..fc5fb333ca5 100644
--- a/packages/react/src/__tests__/createReactClassIntegration-test.js
+++ b/packages/react/src/__tests__/createReactClassIntegration-test.js
@@ -433,6 +433,40 @@ describe('create-react-class-integration', () => {
expect(instance.state.foo).toBe('bar');
});
+ it('warns if getDerivedStateFromProps is not static', () => {
+ const Foo = createReactClass({
+ getDerivedStateFromProps() {
+ return {};
+ },
+ render() {
+ return ;
+ },
+ });
+ expect(() =>
+ ReactDOM.render(, document.createElement('div')),
+ ).toWarnDev(
+ 'Component: getDerivedStateFromProps() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.',
+ );
+ });
+
+ it('warns if getDerivedStateFromCatch is not static', () => {
+ const Foo = createReactClass({
+ getDerivedStateFromCatch() {
+ return {};
+ },
+ render() {
+ return ;
+ },
+ });
+ expect(() =>
+ ReactDOM.render(, document.createElement('div')),
+ ).toWarnDev(
+ 'Component: getDerivedStateFromCatch() is defined as an instance method ' +
+ 'and will be ignored. Instead, declare it as a static method.',
+ );
+ });
+
it('should warn if state is not properly initialized before getDerivedStateFromProps', () => {
const Component = createReactClass({
statics: {