Enhance get derived state from props state warning - #12670 (#13317)
* Enhance warning message for missing state with getDerivedStateFromProps * Adapt tests * style fix * Tweak da message * Fix test
Felix Wu committed
Aug 3, 2018 at 17:09 UTC
b179bae0ae3a9d80bfbe440c8861786b7f928ce1
8 files changed
+41
-16
packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+4
-2
@@ -1003,8 +1003,10 @@ describe('ReactComponentLifeCycle', () => {
1003
1004
const div = document.createElement('div');
1005
expect(() => ReactDOM.render(<MyComponent />, div)).toWarnDev(
1006
- 'MyComponent: Did not properly initialize state during construction. ' +
1007
- 'Expected state to be an object, but it was undefined.',
1006
+ '`MyComponent` uses `getDerivedStateFromProps` but its initial state is ' +
1007
+ 'undefined. This is not recommended. Instead, define the initial state by ' +
1008
+ 'assigning an object to `this.state` in the constructor of `MyComponent`. ' +
1009
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
1010
{withoutStack: true},
1011
);
1012
packages/react-dom/src/__tests__/ReactDOMServerLifecycles-test.js
+4
-2
@@ -201,8 +201,10 @@ describe('ReactDOMServerLifecycles', () => {
201
}
202
203
expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
204
- 'Component: Did not properly initialize state during construction. ' +
205
- 'Expected state to be an object, but it was undefined.',
204
+ '`Component` uses `getDerivedStateFromProps` but its initial state is ' +
205
+ 'undefined. This is not recommended. Instead, define the initial state by ' +
206
+ 'assigning an object to `this.state` in the constructor of `Component`. ' +
207
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
208
{withoutStack: true},
209
);
210
packages/react-dom/src/server/ReactPartialRenderer.js
+5
-2
@@ -476,10 +476,13 @@ function resolve(
476
if (!didWarnAboutUninitializedState[componentName]) {
477
warningWithoutStack(
478
false,
479
- '%s: Did not properly initialize state during construction. ' +
480
- 'Expected state to be an object, but it was %s.',
479
+ '`%s` uses `getDerivedStateFromProps` but its initial state is ' +
480
+ '%s. This is not recommended. Instead, define the initial state by ' +
481
+ 'assigning an object to `this.state` in the constructor of `%s`. ' +
482
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
483
componentName,
484
inst.state === null ? 'null' : 'undefined',
485
+ componentName,
486
);
487
didWarnAboutUninitializedState[componentName] = true;
488
}
packages/react-reconciler/src/ReactFiberClassComponent.js
+5
-2
@@ -505,10 +505,13 @@ function constructClassInstance(
505
didWarnAboutUninitializedState.add(componentName);
506
warningWithoutStack(
507
false,
508
- '%s: Did not properly initialize state during construction. ' +
509
- 'Expected state to be an object, but it was %s.',
508
+ '`%s` uses `getDerivedStateFromProps` but its initial state is ' +
509
+ '%s. This is not recommended. Instead, define the initial state by ' +
510
+ 'assigning an object to `this.state` in the constructor of `%s`. ' +
511
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
512
componentName,
513
instance.state === null ? 'null' : 'undefined',
514
+ componentName,
515
);
516
}
517
}
packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
+6
-1
@@ -163,7 +163,12 @@ describe 'ReactCoffeeScriptClass', ->
163
}
164
expect(->
165
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
166
- ).toWarnDev 'Foo: Did not properly initialize state during construction. Expected state to be an object, but it was undefined.', {withoutStack: true}
166
+ ).toWarnDev (
167
+ '`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
168
+ 'undefined. This is not recommended. Instead, define the initial state by ' +
169
+ 'assigning an object to `this.state` in the constructor of `Foo`. ' +
170
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.'
171
+ ), {withoutStack: true}
172
undefined
173
174
it 'updates initial state with values returned by static getDerivedStateFromProps', ->
packages/react/src/__tests__/ReactES6Class-test.js
+4
-2
@@ -190,8 +190,10 @@ describe('ReactES6Class', () => {
190
}
191
}
192
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
193
- 'Foo: Did not properly initialize state during construction. ' +
194
- 'Expected state to be an object, but it was undefined.',
193
+ '`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
194
+ 'undefined. This is not recommended. Instead, define the initial state by ' +
195
+ 'assigning an object to `this.state` in the constructor of `Foo`. ' +
196
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
197
{withoutStack: true},
198
);
199
});
packages/react/src/__tests__/ReactTypeScriptClass-test.ts
+4
-2
@@ -448,8 +448,10 @@ describe('ReactTypeScriptClass', function() {
448
expect(function() {
449
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
450
}).toWarnDev(
451
- 'Foo: Did not properly initialize state during construction. ' +
452
- 'Expected state to be an object, but it was undefined.',
451
+ '`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
452
+ 'undefined. This is not recommended. Instead, define the initial state by ' +
453
+ 'assigning an object to `this.state` in the constructor of `Foo`. ' +
454
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
455
{withoutStack: true}
456
);
457
});
packages/react/src/__tests__/createReactClassIntegration-test.js
+9
-3
@@ -510,9 +510,15 @@ describe('create-react-class-integration', () => {
510
});
511
expect(() =>
512
ReactDOM.render(<Component />, document.createElement('div')),
513
- ).toWarnDev('Did not properly initialize state during construction.', {
514
- withoutStack: true,
515
- });
513
+ ).toWarnDev(
514
+ '`Component` uses `getDerivedStateFromProps` but its initial state is ' +
515
+ 'null. This is not recommended. Instead, define the initial state by ' +
516
+ 'assigning an object to `this.state` in the constructor of `Component`. ' +
517
+ 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
518
+ {
519
+ withoutStack: true,
520
+ },
521
+ );
522
});
523
524
it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {