Skip to content

Commit

Permalink
Enhance get derived state from props state warning - #12670 (#13317)
Browse files Browse the repository at this point in the history
* Enhance warning message for missing state with getDerivedStateFromProps

* Adapt tests

* style fix

* Tweak da message

* Fix test
  • Loading branch information
Felix Wu authored and gaearon committed Aug 3, 2018
1 parent fa824d0 commit b179bae
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1003,8 +1003,10 @@ describe('ReactComponentLifeCycle', () => {

const div = document.createElement('div');
expect(() => ReactDOM.render(<MyComponent />, div)).toWarnDev(
'MyComponent: Did not properly initialize state during construction. ' +
'Expected state to be an object, but it was undefined.',
'`MyComponent` uses `getDerivedStateFromProps` but its initial state is ' +
'undefined. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `MyComponent`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
{withoutStack: true},
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,10 @@ describe('ReactDOMServerLifecycles', () => {
}

expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
'Component: Did not properly initialize state during construction. ' +
'Expected state to be an object, but it was undefined.',
'`Component` uses `getDerivedStateFromProps` but its initial state is ' +
'undefined. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `Component`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
{withoutStack: true},
);

Expand Down
7 changes: 5 additions & 2 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,13 @@ function resolve(
if (!didWarnAboutUninitializedState[componentName]) {
warningWithoutStack(
false,
'%s: Did not properly initialize state during construction. ' +
'Expected state to be an object, but it was %s.',
'`%s` uses `getDerivedStateFromProps` but its initial state is ' +
'%s. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `%s`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
componentName,
inst.state === null ? 'null' : 'undefined',
componentName,
);
didWarnAboutUninitializedState[componentName] = true;
}
Expand Down
7 changes: 5 additions & 2 deletions packages/react-reconciler/src/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,13 @@ function constructClassInstance(
didWarnAboutUninitializedState.add(componentName);
warningWithoutStack(
false,
'%s: Did not properly initialize state during construction. ' +
'Expected state to be an object, but it was %s.',
'`%s` uses `getDerivedStateFromProps` but its initial state is ' +
'%s. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `%s`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
componentName,
instance.state === null ? 'null' : 'undefined',
componentName,
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,12 @@ describe 'ReactCoffeeScriptClass', ->
}
expect(->
ReactDOM.render(React.createElement(Foo, foo: 'foo'), container)
).toWarnDev 'Foo: Did not properly initialize state during construction. Expected state to be an object, but it was undefined.', {withoutStack: true}
).toWarnDev (
'`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
'undefined. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `Foo`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.'
), {withoutStack: true}
undefined

it 'updates initial state with values returned by static getDerivedStateFromProps', ->
Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/__tests__/ReactES6Class-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,10 @@ describe('ReactES6Class', () => {
}
}
expect(() => ReactDOM.render(<Foo foo="foo" />, container)).toWarnDev(
'Foo: Did not properly initialize state during construction. ' +
'Expected state to be an object, but it was undefined.',
'`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
'undefined. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `Foo`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
{withoutStack: true},
);
});
Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/__tests__/ReactTypeScriptClass-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,10 @@ describe('ReactTypeScriptClass', function() {
expect(function() {
ReactDOM.render(React.createElement(Foo, {foo: 'foo'}), container);
}).toWarnDev(
'Foo: Did not properly initialize state during construction. ' +
'Expected state to be an object, but it was undefined.',
'`Foo` uses `getDerivedStateFromProps` but its initial state is ' +
'undefined. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `Foo`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
{withoutStack: true}
);
});
Expand Down
12 changes: 9 additions & 3 deletions packages/react/src/__tests__/createReactClassIntegration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,15 @@ describe('create-react-class-integration', () => {
});
expect(() =>
ReactDOM.render(<Component />, document.createElement('div')),
).toWarnDev('Did not properly initialize state during construction.', {
withoutStack: true,
});
).toWarnDev(
'`Component` uses `getDerivedStateFromProps` but its initial state is ' +
'null. This is not recommended. Instead, define the initial state by ' +
'assigning an object to `this.state` in the constructor of `Component`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
{
withoutStack: true,
},
);
});

it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {
Expand Down

0 comments on commit b179bae

Please sign in to comment.