mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Expanded DEV-only warnings for gDSFP and legacy lifecycles (#12419)
This commit is contained in:
@@ -669,7 +669,7 @@ describe('ReactComponentLifeCycle', () => {
|
||||
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<Component />, container)).toWarnDev(
|
||||
'Defines both componentWillReceiveProps',
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -695,7 +695,93 @@ describe('ReactComponentLifeCycle', () => {
|
||||
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<Component />, container)).toWarnDev(
|
||||
'Defines both componentWillReceiveProps',
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn about deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
class AllLegacyLifecycles extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
componentWillMount() {}
|
||||
UNSAFE_componentWillReceiveProps() {}
|
||||
componentWillUpdate() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactDOM.render(<AllLegacyLifecycles />, container)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'AllLegacyLifecycles uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillMount\n' +
|
||||
' UNSAFE_componentWillReceiveProps\n' +
|
||||
' componentWillUpdate\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
|
||||
class WillMount extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
UNSAFE_componentWillMount() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactDOM.render(<WillMount />, container)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'WillMount uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' UNSAFE_componentWillMount\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
|
||||
class WillMountAndUpdate extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
componentWillMount() {}
|
||||
UNSAFE_componentWillUpdate() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactDOM.render(<WillMountAndUpdate />, container)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'WillMountAndUpdate uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillMount\n' +
|
||||
' UNSAFE_componentWillUpdate\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
|
||||
class WillReceiveProps extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
componentWillReceiveProps() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactDOM.render(<WillReceiveProps />, container)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'WillReceiveProps uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillReceiveProps\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+71
-38
@@ -41,14 +41,14 @@ const isArray = Array.isArray;
|
||||
let didWarnAboutStateAssignmentForComponent;
|
||||
let didWarnAboutUndefinedDerivedState;
|
||||
let didWarnAboutUninitializedState;
|
||||
let didWarnAboutWillReceivePropsAndDerivedState;
|
||||
let didWarnAboutLegacyLifecyclesAndDerivedState;
|
||||
let warnOnInvalidCallback;
|
||||
|
||||
if (__DEV__) {
|
||||
didWarnAboutStateAssignmentForComponent = {};
|
||||
didWarnAboutUndefinedDerivedState = {};
|
||||
didWarnAboutUninitializedState = {};
|
||||
didWarnAboutWillReceivePropsAndDerivedState = {};
|
||||
didWarnAboutLegacyLifecyclesAndDerivedState = {};
|
||||
|
||||
const didWarnOnInvalidCallback = {};
|
||||
|
||||
@@ -435,20 +435,75 @@ export default function(
|
||||
adoptClassInstance(workInProgress, instance);
|
||||
|
||||
if (__DEV__) {
|
||||
if (
|
||||
typeof ctor.getDerivedStateFromProps === 'function' &&
|
||||
state === null
|
||||
) {
|
||||
const componentName = getComponentName(workInProgress) || 'Component';
|
||||
if (!didWarnAboutUninitializedState[componentName]) {
|
||||
warning(
|
||||
false,
|
||||
'%s: Did not properly initialize state during construction. ' +
|
||||
'Expected state to be an object, but it was %s.',
|
||||
componentName,
|
||||
instance.state === null ? 'null' : 'undefined',
|
||||
);
|
||||
didWarnAboutUninitializedState[componentName] = true;
|
||||
if (typeof ctor.getDerivedStateFromProps === 'function') {
|
||||
if (state === null) {
|
||||
const componentName = getComponentName(workInProgress) || 'Component';
|
||||
if (!didWarnAboutUninitializedState[componentName]) {
|
||||
warning(
|
||||
false,
|
||||
'%s: Did not properly initialize state during construction. ' +
|
||||
'Expected state to be an object, but it was %s.',
|
||||
componentName,
|
||||
instance.state === null ? 'null' : 'undefined',
|
||||
);
|
||||
didWarnAboutUninitializedState[componentName] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If getDerivedStateFromProps() is defined, "unsafe" lifecycles won't be called.
|
||||
// Warn about these lifecycles if they are present.
|
||||
// Don't warn about react-lifecycles-compat polyfilled methods though.
|
||||
let foundWillMountName = null;
|
||||
let foundWillReceivePropsName = null;
|
||||
let foundWillUpdateName = null;
|
||||
if (
|
||||
typeof instance.componentWillMount === 'function' &&
|
||||
instance.componentWillMount.__suppressDeprecationWarning !== true
|
||||
) {
|
||||
foundWillMountName = 'componentWillMount';
|
||||
} else if (typeof instance.UNSAFE_componentWillMount === 'function') {
|
||||
foundWillMountName = 'UNSAFE_componentWillMount';
|
||||
}
|
||||
if (
|
||||
typeof instance.componentWillReceiveProps === 'function' &&
|
||||
instance.componentWillReceiveProps.__suppressDeprecationWarning !==
|
||||
true
|
||||
) {
|
||||
foundWillReceivePropsName = 'componentWillReceiveProps';
|
||||
} else if (
|
||||
typeof instance.UNSAFE_componentWillReceiveProps === 'function'
|
||||
) {
|
||||
foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
|
||||
}
|
||||
if (typeof instance.componentWillUpdate === 'function') {
|
||||
foundWillUpdateName = 'componentWillUpdate';
|
||||
} else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
|
||||
foundWillUpdateName = 'UNSAFE_componentWillUpdate';
|
||||
}
|
||||
if (
|
||||
foundWillMountName !== null ||
|
||||
foundWillReceivePropsName !== null ||
|
||||
foundWillUpdateName !== null
|
||||
) {
|
||||
const componentName = getComponentName(workInProgress) || 'Component';
|
||||
if (!didWarnAboutLegacyLifecyclesAndDerivedState[componentName]) {
|
||||
warning(
|
||||
false,
|
||||
'Unsafe legacy lifecycles will not be called for components using ' +
|
||||
'the new getDerivedStateFromProps() API.\n\n' +
|
||||
'%s uses getDerivedStateFromProps() but also contains the following legacy lifecycles:' +
|
||||
'%s%s%s\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
componentName,
|
||||
foundWillMountName !== null ? `\n ${foundWillMountName}` : '',
|
||||
foundWillReceivePropsName !== null
|
||||
? `\n ${foundWillReceivePropsName}`
|
||||
: '',
|
||||
foundWillUpdateName !== null ? `\n ${foundWillUpdateName}` : '',
|
||||
);
|
||||
didWarnAboutLegacyLifecyclesAndDerivedState[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -552,28 +607,6 @@ export default function(
|
||||
const {type} = workInProgress;
|
||||
|
||||
if (typeof type.getDerivedStateFromProps === 'function') {
|
||||
if (__DEV__) {
|
||||
// Don't warn about react-lifecycles-compat polyfilled components
|
||||
if (
|
||||
(typeof instance.componentWillReceiveProps === 'function' &&
|
||||
instance.componentWillReceiveProps.__suppressDeprecationWarning !==
|
||||
true) ||
|
||||
typeof instance.UNSAFE_componentWillReceiveProps === 'function'
|
||||
) {
|
||||
const componentName = getComponentName(workInProgress) || 'Component';
|
||||
if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) {
|
||||
warning(
|
||||
false,
|
||||
'%s: Defines both componentWillReceiveProps() and static ' +
|
||||
'getDerivedStateFromProps() methods. We recommend using ' +
|
||||
'only getDerivedStateFromProps().',
|
||||
componentName,
|
||||
);
|
||||
didWarnAboutWillReceivePropsAndDerivedState[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
debugRenderPhaseSideEffects ||
|
||||
(debugRenderPhaseSideEffectsForStrictMode &&
|
||||
|
||||
+51
-13
@@ -23,7 +23,7 @@ let didWarnAboutLegacyWillReceiveProps;
|
||||
let didWarnAboutLegacyWillUpdate;
|
||||
let didWarnAboutUndefinedDerivedState;
|
||||
let didWarnAboutUninitializedState;
|
||||
let didWarnAboutWillReceivePropsAndDerivedState;
|
||||
let didWarnAboutLegacyLifecyclesAndDerivedState;
|
||||
|
||||
if (__DEV__) {
|
||||
if (warnAboutDeprecatedLifecycles) {
|
||||
@@ -33,7 +33,7 @@ if (__DEV__) {
|
||||
}
|
||||
didWarnAboutUndefinedDerivedState = {};
|
||||
didWarnAboutUninitializedState = {};
|
||||
didWarnAboutWillReceivePropsAndDerivedState = {};
|
||||
didWarnAboutLegacyLifecyclesAndDerivedState = {};
|
||||
}
|
||||
|
||||
class ReactShallowRenderer {
|
||||
@@ -352,23 +352,61 @@ class ReactShallowRenderer {
|
||||
|
||||
if (typeof type.getDerivedStateFromProps === 'function') {
|
||||
if (__DEV__) {
|
||||
// Don't warn about react-lifecycles-compat polyfilled components
|
||||
const instance = this._instance;
|
||||
|
||||
// If getDerivedStateFromProps() is defined, "unsafe" lifecycles won't be called.
|
||||
// Warn about these lifecycles if they are present.
|
||||
// Don't warn about react-lifecycles-compat polyfilled methods though.
|
||||
let foundWillMountName = null;
|
||||
let foundWillReceivePropsName = null;
|
||||
let foundWillUpdateName = null;
|
||||
if (
|
||||
(typeof this._instance.componentWillReceiveProps === 'function' &&
|
||||
this._instance.componentWillReceiveProps
|
||||
.__suppressDeprecationWarning !== true) ||
|
||||
typeof this._instance.UNSAFE_componentWillReceiveProps === 'function'
|
||||
typeof instance.componentWillMount === 'function' &&
|
||||
instance.componentWillMount.__suppressDeprecationWarning !== true
|
||||
) {
|
||||
const componentName = getName(type, this._instance);
|
||||
if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) {
|
||||
foundWillMountName = 'componentWillMount';
|
||||
} else if (typeof instance.UNSAFE_componentWillMount === 'function') {
|
||||
foundWillMountName = 'UNSAFE_componentWillMount';
|
||||
}
|
||||
if (
|
||||
typeof instance.componentWillReceiveProps === 'function' &&
|
||||
instance.componentWillReceiveProps.__suppressDeprecationWarning !==
|
||||
true
|
||||
) {
|
||||
foundWillReceivePropsName = 'componentWillReceiveProps';
|
||||
} else if (
|
||||
typeof instance.UNSAFE_componentWillReceiveProps === 'function'
|
||||
) {
|
||||
foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
|
||||
}
|
||||
if (typeof instance.componentWillUpdate === 'function') {
|
||||
foundWillUpdateName = 'componentWillUpdate';
|
||||
} else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
|
||||
foundWillUpdateName = 'UNSAFE_componentWillUpdate';
|
||||
}
|
||||
if (
|
||||
foundWillMountName !== null ||
|
||||
foundWillReceivePropsName !== null ||
|
||||
foundWillUpdateName !== null
|
||||
) {
|
||||
const componentName = getName(type, instance) || 'Component';
|
||||
if (!didWarnAboutLegacyLifecyclesAndDerivedState[componentName]) {
|
||||
warning(
|
||||
false,
|
||||
'%s: Defines both componentWillReceiveProps() and static ' +
|
||||
'getDerivedStateFromProps() methods. We recommend using ' +
|
||||
'only getDerivedStateFromProps().',
|
||||
'Unsafe legacy lifecycles will not be called for components using ' +
|
||||
'the new getDerivedStateFromProps() API.\n\n' +
|
||||
'%s uses getDerivedStateFromProps() but also contains the following legacy lifecycles:' +
|
||||
'%s%s%s\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
componentName,
|
||||
foundWillMountName !== null ? `\n ${foundWillMountName}` : '',
|
||||
foundWillReceivePropsName !== null
|
||||
? `\n ${foundWillReceivePropsName}`
|
||||
: '',
|
||||
foundWillUpdateName !== null ? `\n ${foundWillUpdateName}` : '',
|
||||
);
|
||||
didWarnAboutWillReceivePropsAndDerivedState[componentName] = true;
|
||||
didWarnAboutLegacyLifecyclesAndDerivedState[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +125,98 @@ describe('ReactShallowRenderer', () => {
|
||||
}
|
||||
|
||||
const shallowRenderer = createRenderer();
|
||||
expect(() => shallowRenderer.render(<Component foo={2} />)).toWarnDev(
|
||||
'Defines both componentWillReceiveProps() and static getDerivedStateFromProps()',
|
||||
expect(() => shallowRenderer.render(<Component />)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn about deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {
|
||||
let shallowRenderer;
|
||||
|
||||
class AllLegacyLifecycles extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
componentWillMount() {}
|
||||
UNSAFE_componentWillReceiveProps() {}
|
||||
componentWillUpdate() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
shallowRenderer = createRenderer();
|
||||
expect(() => shallowRenderer.render(<AllLegacyLifecycles />)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'AllLegacyLifecycles uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillMount\n' +
|
||||
' UNSAFE_componentWillReceiveProps\n' +
|
||||
' componentWillUpdate\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
|
||||
class WillMount extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
UNSAFE_componentWillMount() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
shallowRenderer = createRenderer();
|
||||
expect(() => shallowRenderer.render(<WillMount />)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'WillMount uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' UNSAFE_componentWillMount\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
|
||||
class WillMountAndUpdate extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
componentWillMount() {}
|
||||
UNSAFE_componentWillUpdate() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
shallowRenderer = createRenderer();
|
||||
expect(() => shallowRenderer.render(<WillMountAndUpdate />)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'WillMountAndUpdate uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillMount\n' +
|
||||
' UNSAFE_componentWillUpdate\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
|
||||
class WillReceiveProps extends React.Component {
|
||||
state = {};
|
||||
static getDerivedStateFromProps() {
|
||||
return null;
|
||||
}
|
||||
componentWillReceiveProps() {}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
shallowRenderer = createRenderer();
|
||||
expect(() => shallowRenderer.render(<WillReceiveProps />)).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'WillReceiveProps uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillReceiveProps\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1238,9 +1328,7 @@ describe('ReactShallowRenderer', () => {
|
||||
|
||||
const shallowRenderer = createRenderer();
|
||||
expect(() => shallowRenderer.render(<ComponentWithWarnings />)).toWarnDev(
|
||||
'ComponentWithWarnings: Defines both componentWillReceiveProps() and static ' +
|
||||
'getDerivedStateFromProps() methods. We recommend using ' +
|
||||
'only getDerivedStateFromProps().',
|
||||
'ComponentWithWarnings uses getDerivedStateFromProps() but also contains the following legacy lifecycles',
|
||||
);
|
||||
|
||||
// Should not log duplicate warning
|
||||
|
||||
@@ -509,7 +509,15 @@ describe('create-react-class-integration', () => {
|
||||
|
||||
expect(() => {
|
||||
ReactDOM.render(<Component />, document.createElement('div'));
|
||||
}).toWarnDev('Defines both componentWillReceiveProps');
|
||||
}).toWarnDev(
|
||||
'Unsafe legacy lifecycles will not be called for components using the new getDerivedStateFromProps() API.\n\n' +
|
||||
'Component uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
|
||||
' componentWillMount\n' +
|
||||
' componentWillReceiveProps\n' +
|
||||
' componentWillUpdate\n\n' +
|
||||
'The above lifecycles should be removed. Learn more about this warning here:\n' +
|
||||
'https://fb.me/react-async-component-lifecycle-hooks',
|
||||
);
|
||||
ReactDOM.render(<Component foo={1} />, document.createElement('div'));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user