@samitouri / QOS-React / commits / 0af384b4c3

Warn about non-static getDerivedStateFromProps/Catch (#12431)

Dan Abramov committed Mar 22, 2018 at 17:54 UTC 0af384b4c33bf7d039f513e0869665824e08bb6b
5 files changed +136
packages/react-reconciler/src/ReactFiberClassComponent.js
+16
@@ -364,6 +364,22 @@ export default function(
364 name,
365 name,
366 );
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 + );
383 const state = instance.state;
384 if (state && (typeof state !== 'object' || isArray(state))) {
385 warning(false, '%s.state: must be set to an object or null', name);
packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
+22
@@ -118,6 +118,28 @@ describe 'ReactCoffeeScriptClass', ->
118 test React.createElement(Foo, foo: 'foo'), 'DIV', 'foo bar'
119 undefined
120
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 +
143 it 'warns if state not initialized before static getDerivedStateFromProps', ->
144 class Foo extends React.Component
145 render: ->
packages/react/src/__tests__/ReactES6Class-test.js
+30
@@ -128,6 +128,36 @@ describe('ReactES6Class', () => {
128 test(<Foo foo="foo" />, 'DIV', 'foo bar');
129 });
130
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 +
161 it('warns if state not initialized before static getDerivedStateFromProps', () => {
162 class Foo extends React.Component {
163 static getDerivedStateFromProps(nextProps, prevState) {
packages/react/src/__tests__/ReactTypeScriptClass-test.ts
+34
@@ -378,6 +378,40 @@ describe('ReactTypeScriptClass', function() {
378 test(React.createElement(Foo, {foo: 'foo'}), 'DIV', 'foo bar');
379 });
380
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 +
415 it('warns if state not initialized before static getDerivedStateFromProps', function() {
416 class Foo extends React.Component {
417 static getDerivedStateFromProps(nextProps, prevState) {
packages/react/src/__tests__/createReactClassIntegration-test.js
+34
@@ -433,6 +433,40 @@ describe('create-react-class-integration', () => {
433 expect(instance.state.foo).toBe('bar');
434 });
435
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 +
470 it('should warn if state is not properly initialized before getDerivedStateFromProps', () => {
471 const Component = createReactClass({
472 statics: {