Skip to content

Commit fe94472

Browse files
gaearonLeonYuAng3NT
authored andcommitted
Warn about non-static getDerivedStateFromProps/Catch (facebook#12431)
1 parent fc0f9c0 commit fe94472

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

packages/react-reconciler/src/ReactFiberClassComponent.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,22 @@ export default function(
364364
name,
365365
name,
366366
);
367+
const noInstanceGetDerivedStateFromProps =
368+
typeof instance.getDerivedStateFromProps !== 'function';
369+
warning(
370+
noInstanceGetDerivedStateFromProps,
371+
'%s: getDerivedStateFromProps() is defined as an instance method ' +
372+
'and will be ignored. Instead, declare it as a static method.',
373+
name,
374+
);
375+
const noInstanceGetDerivedStateFromCatch =
376+
typeof instance.getDerivedStateFromCatch !== 'function';
377+
warning(
378+
noInstanceGetDerivedStateFromCatch,
379+
'%s: getDerivedStateFromCatch() is defined as an instance method ' +
380+
'and will be ignored. Instead, declare it as a static method.',
381+
name,
382+
);
367383
const state = instance.state;
368384
if (state && (typeof state !== 'object' || isArray(state))) {
369385
warning(false, '%s.state: must be set to an object or null', name);

packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,28 @@ describe 'ReactCoffeeScriptClass', ->
118118
test React.createElement(Foo, foo: 'foo'), 'DIV', 'foo bar'
119119
undefined
120120

121+
it 'warns if getDerivedStateFromProps is not static', ->
122+
class Foo extends React.Component
123+
render: ->
124+
div()
125+
getDerivedStateFromProps: ->
126+
{}
127+
expect(->
128+
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
129+
).toWarnDev 'Foo: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.',
130+
undefined
131+
132+
it 'warns if getDerivedStateFromCatch is not static', ->
133+
class Foo extends React.Component
134+
render: ->
135+
div()
136+
getDerivedStateFromCatch: ->
137+
{}
138+
expect(->
139+
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
140+
).toWarnDev 'Foo: getDerivedStateFromCatch() is defined as an instance method and will be ignored. Instead, declare it as a static method.',
141+
undefined
142+
121143
it 'warns if state not initialized before static getDerivedStateFromProps', ->
122144
class Foo extends React.Component
123145
render: ->

packages/react/src/__tests__/ReactES6Class-test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,36 @@ describe('ReactES6Class', () => {
128128
test(<Foo foo="foo" />, 'DIV', 'foo bar');
129129
});
130130

131+
it('warns if getDerivedStateFromProps is not static', () => {
132+
class Foo extends React.Component {
133+
getDerivedStateFromProps() {
134+
return {};
135+
}
136+
render() {
137+
return <div />;
138+
}
139+
}
140+
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
141+
'Foo: getDerivedStateFromProps() is defined as an instance method ' +
142+
'and will be ignored. Instead, declare it as a static method.',
143+
);
144+
});
145+
146+
it('warns if getDerivedStateFromCatch is not static', () => {
147+
class Foo extends React.Component {
148+
getDerivedStateFromCatch() {
149+
return {};
150+
}
151+
render() {
152+
return <div />;
153+
}
154+
}
155+
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
156+
'Foo: getDerivedStateFromCatch() is defined as an instance method ' +
157+
'and will be ignored. Instead, declare it as a static method.',
158+
);
159+
});
160+
131161
it('warns if state not initialized before static getDerivedStateFromProps', () => {
132162
class Foo extends React.Component {
133163
static getDerivedStateFromProps(nextProps, prevState) {

packages/react/src/__tests__/ReactTypeScriptClass-test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,40 @@ describe('ReactTypeScriptClass', function() {
378378
test(React.createElement(Foo, {foo: 'foo'}), 'DIV', 'foo bar');
379379
});
380380

381+
it('warns if getDerivedStateFromProps is not static', function() {
382+
class Foo extends React.Component {
383+
getDerivedStateFromProps() {
384+
return {};
385+
}
386+
render() {
387+
return React.createElement('div', {});
388+
}
389+
}
390+
expect(function() {
391+
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
392+
}).toWarnDev(
393+
'Foo: getDerivedStateFromProps() is defined as an instance method ' +
394+
'and will be ignored. Instead, declare it as a static method.'
395+
);
396+
});
397+
398+
it('warns if getDerivedStateFromCatch is not static', function() {
399+
class Foo extends React.Component {
400+
getDerivedStateFromCatch() {
401+
return {};
402+
}
403+
render() {
404+
return React.createElement('div');
405+
}
406+
}
407+
expect(function() {
408+
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
409+
}).toWarnDev(
410+
'Foo: getDerivedStateFromCatch() is defined as an instance method ' +
411+
'and will be ignored. Instead, declare it as a static method.'
412+
);
413+
});
414+
381415
it('warns if state not initialized before static getDerivedStateFromProps', function() {
382416
class Foo extends React.Component {
383417
static getDerivedStateFromProps(nextProps, prevState) {

packages/react/src/__tests__/createReactClassIntegration-test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,40 @@ describe('create-react-class-integration', () => {
433433
expect(instance.state.foo).toBe('bar');
434434
});
435435

436+
it('warns if getDerivedStateFromProps is not static', () => {
437+
const Foo = createReactClass({
438+
getDerivedStateFromProps() {
439+
return {};
440+
},
441+
render() {
442+
return <div />;
443+
},
444+
});
445+
expect(() =>
446+
ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
447+
).toWarnDev(
448+
'Component: getDerivedStateFromProps() is defined as an instance method ' +
449+
'and will be ignored. Instead, declare it as a static method.',
450+
);
451+
});
452+
453+
it('warns if getDerivedStateFromCatch is not static', () => {
454+
const Foo = createReactClass({
455+
getDerivedStateFromCatch() {
456+
return {};
457+
},
458+
render() {
459+
return <div />;
460+
},
461+
});
462+
expect(() =>
463+
ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
464+
).toWarnDev(
465+
'Component: getDerivedStateFromCatch() is defined as an instance method ' +
466+
'and will be ignored. Instead, declare it as a static method.',
467+
);
468+
});
469+
436470
it('should warn if state is not properly initialized before getDerivedStateFromProps', () => {
437471
const Component = createReactClass({
438472
statics: {

0 commit comments

Comments
 (0)