Add warning to prevent setting this.state to this.props referentially (#11658)

* add test to warn if setting this.state to this.props referentially

* Avoid an extra check
This commit is contained in:
Veekas Shrivastava authored and Dan Abramov committed 2018-08-28 14:17:44 +01:00
1 parent 29287f0886
commit 672e859d31
2 files changed
+37

No files matched your search

@@ -198,6 +198,27 @@ describe('ReactComponentLifeCycle', () => {
}).not.toThrow();
});
it("warns if setting 'this.state = props'", () => {
class StatefulComponent extends React.Component {
constructor(props, context) {
super(props, context);
this.state = props;
}
render() {
return <div />;
}
}
expect(() => {
ReactTestUtils.renderIntoDocument(<StatefulComponent />);
}).toWarnDev(
'StatefulComponent: It is not recommended to assign props directly to state ' +
"because updates to props won't be reflected in state. " +
'In most cases, it is better to use props directly.',
{withoutStack: true},
);
});
it('should not allow update state inside of getInitialState', () => {
class StatefulComponent extends React.Component {
constructor(props, context) {
@@ -64,12 +64,14 @@ let didWarnAboutLegacyLifecyclesAndDerivedState;
let didWarnAboutUndefinedDerivedState;
let warnOnUndefinedDerivedState;
let warnOnInvalidCallback;
let didWarnAboutDirectlyAssigningPropsToState;
if (__DEV__) {
didWarnAboutStateAssignmentForComponent = new Set();
didWarnAboutUninitializedState = new Set();
didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
didWarnAboutDirectlyAssigningPropsToState = new Set();
didWarnAboutUndefinedDerivedState = new Set();
const didWarnOnInvalidCallback = new Set();
@@ -674,6 +676,20 @@ function mountClassInstance(
instance.context = getMaskedContext(workInProgress, unmaskedContext);
if (__DEV__) {
if (instance.state === newProps) {
const componentName = getComponentName(ctor) || 'Component';
if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
didWarnAboutDirectlyAssigningPropsToState.add(componentName);
warningWithoutStack(
false,
'%s: It is not recommended to assign props directly to state ' +
"because updates to props won't be reflected in state. " +
'In most cases, it is better to use props directly.',
componentName,
);
}
}
if (workInProgress.mode & StrictMode) {
ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(
workInProgress,