mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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:
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,
|
||||
|
||||
Reference in new issue
Block a user