Skip to content

Commit

Permalink
Moved lifecycle deprecation warnings behind (disabled) feature flag
Browse files Browse the repository at this point in the history
Updated tests accordingly, by temporarily splitting tests that were specific to this feature-flag into their own, internal tests. This was the only way I knew of to interact with the feature flag without breaking our build/dist tests.
  • Loading branch information
bvaughn committed Jan 18, 2018
1 parent 68f2fe7 commit 2d9f75d
Show file tree
Hide file tree
Showing 15 changed files with 395 additions and 244 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/

'use strict';

let React;
let ReactDOM;
let ReactFeatureFlags;

/**
* TODO: We should make any setState calls fail in
* `getInitialState` and `componentWillMount`. They will usually fail
* anyways because `this._renderedComponent` is empty, however, if a component
* is *reused*, then that won't be the case and things will appear to work in
* some cases. Better to just block all updates in initialization.
*/
describe('ReactComponentLifeCycle', () => {
beforeEach(() => {
jest.resetModules();

ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.warnAboutDeprecatedLifecycles = true;

React = require('react');
ReactDOM = require('react-dom');
});

// TODO (RFC #6) Merge this back into ReactComponentLifeCycles-test once
// the 'warnAboutDeprecatedLifecycles' feature flag has been removed.
it('warns about deprecated unsafe lifecycles', function() {
class MyComponent extends React.Component {
componentWillMount() {}
componentWillReceiveProps() {}
componentWillUpdate() {}
render() {
return null;
}
}

const container = document.createElement('div');
expect(() => ReactDOM.render(<MyComponent x={1} />, container)).toWarnDev([
'Warning: MyComponent: componentWillMount() is deprecated and will be ' +
'removed in the next major version. ' +
'Please use UNSAFE_componentWillMount() instead.',
]);

expect(() => ReactDOM.render(<MyComponent x={2} />, container)).toWarnDev([
'Warning: MyComponent: componentWillReceiveProps() is deprecated and ' +
'will be removed in the next major version. ' +
'Please use UNSAFE_componentWillReceiveProps() instead.',
'Warning: MyComponent: componentWillUpdate() is deprecated and will be ' +
'removed in the next major version. ' +
'Please use UNSAFE_componentWillUpdate() instead.',
]);

// Dedupe check (instantiate and update)
ReactDOM.render(<MyComponent key="new" x={1} />, container);
ReactDOM.render(<MyComponent key="new" x={2} />, container);
});
});
31 changes: 0 additions & 31 deletions packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -593,37 +593,6 @@ describe('ReactComponentLifeCycle', () => {
]);
});

it('warns about deprecated unsafe lifecycles', function() {
class MyComponent extends React.Component {
componentWillMount() {}
componentWillReceiveProps() {}
componentWillUpdate() {}
render() {
return null;
}
}

const container = document.createElement('div');
expect(() => ReactDOM.render(<MyComponent x={1} />, container)).toWarnDev([
'Warning: MyComponent: componentWillMount() is deprecated and will be ' +
'removed in the next major version. ' +
'Please use UNSAFE_componentWillMount() instead.',
]);

expect(() => ReactDOM.render(<MyComponent x={2} />, container)).toWarnDev([
'Warning: MyComponent: componentWillReceiveProps() is deprecated and ' +
'will be removed in the next major version. ' +
'Please use UNSAFE_componentWillReceiveProps() instead.',
'Warning: MyComponent: componentWillUpdate() is deprecated and will be ' +
'removed in the next major version. ' +
'Please use UNSAFE_componentWillUpdate() instead.',
]);

// Dedupe check (instantiate and update)
ReactDOM.render(<MyComponent key="new" x={1} />, container);
ReactDOM.render(<MyComponent key="new" x={2} />, container);
});

it('calls effects on module-pattern component', function() {
const log = [];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/

'use strict';

let React;
let ReactFeatureFlags;
let ReactDOMServer;

describe('ReactDOMServerLifecycles', () => {
beforeEach(() => {
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.warnAboutDeprecatedLifecycles = true;

React = require('react');
ReactDOMServer = require('react-dom/server');
});

// TODO (RFC #6) Merge this back into ReactDOMServerLifecycles-test once
// the 'warnAboutDeprecatedLifecycles' feature flag has been removed.
it('should warn about deprecated lifecycle hooks', () => {
class Component extends React.Component {
componentWillMount() {}
render() {
return null;
}
}

expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
'Warning: Component: componentWillMount() is deprecated and will be removed ' +
'in the next major version. Please use UNSAFE_componentWillMount() instead.',
);

// De-duped
ReactDOMServer.renderToString(<Component />);
});
});
17 changes: 0 additions & 17 deletions packages/react-dom/src/__tests__/ReactDOMServerLifecycles-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,6 @@ describe('ReactDOMServerLifecycles', () => {
]);
});

it('should warn about deprecated lifecycle hooks', () => {
class Component extends React.Component {
componentWillMount() {}
render() {
return null;
}
}

expect(() => ReactDOMServer.renderToString(<Component />)).toWarnDev(
'Warning: Component: componentWillMount() is deprecated and will be removed ' +
'in the next major version. Please use UNSAFE_componentWillMount() instead.',
);

// De-duped
ReactDOMServer.renderToString(<Component />);
});

it('should update instance.state with value returned from getDerivedStateFromProps', () => {
class Grandparent extends React.Component {
state = {
Expand Down
21 changes: 12 additions & 9 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import warning from 'fbjs/lib/warning';
import checkPropTypes from 'prop-types/checkPropTypes';
import describeComponentFrame from 'shared/describeComponentFrame';
import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState';
import {warnAboutDeprecatedLifecycles} from 'shared/ReactFeatureFlags';
import {
REACT_FRAGMENT_TYPE,
REACT_CALL_TYPE,
Expand Down Expand Up @@ -489,16 +490,18 @@ function resolve(
if (inst.UNSAFE_componentWillMount || inst.componentWillMount) {
if (inst.componentWillMount) {
if (__DEV__) {
const componentName = getComponentName(Component) || 'Unknown';
if (warnAboutDeprecatedLifecycles) {
const componentName = getComponentName(Component) || 'Unknown';

if (!didWarnAboutDeprecatedWillMount[componentName]) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillMount() instead.',
componentName,
);
didWarnAboutDeprecatedWillMount[componentName] = true;
if (!didWarnAboutDeprecatedWillMount[componentName]) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillMount() instead.',
componentName,
);
didWarnAboutDeprecatedWillMount[componentName] = true;
}
}
}

Expand Down
71 changes: 40 additions & 31 deletions packages/react-reconciler/src/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {Update} from 'shared/ReactTypeOfSideEffect';
import {
debugRenderPhaseSideEffects,
enableAsyncSubtreeAPI,
warnAboutDeprecatedLifecycles,
} from 'shared/ReactFeatureFlags';
import {isMounted} from 'react-reconciler/reflection';
import * as ReactInstanceMap from 'shared/ReactInstanceMap';
Expand Down Expand Up @@ -49,9 +50,11 @@ let didWarnAboutWillReceivePropsAndDerivedState;
let warnOnInvalidCallback;

if (__DEV__) {
didWarnAboutLegacyWillMount = {};
didWarnAboutLegacyWillReceiveProps = {};
didWarnAboutLegacyWillUpdate = {};
if (warnAboutDeprecatedLifecycles) {
didWarnAboutLegacyWillMount = {};
didWarnAboutLegacyWillReceiveProps = {};
didWarnAboutLegacyWillUpdate = {};
}
didWarnAboutStateAssignmentForComponent = {};
didWarnAboutUndefinedDerivedState = {};
didWarnAboutWillReceivePropsAndDerivedState = {};
Expand Down Expand Up @@ -426,15 +429,17 @@ export default function(

if (typeof instance.componentWillMount === 'function') {
if (__DEV__) {
const componentName = getComponentName(workInProgress) || 'Unknown';
if (!didWarnAboutLegacyWillMount[componentName]) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillMount() instead.',
componentName,
);
didWarnAboutLegacyWillMount[componentName] = true;
if (warnAboutDeprecatedLifecycles) {
const componentName = getComponentName(workInProgress) || 'Unknown';
if (!didWarnAboutLegacyWillMount[componentName]) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillMount() instead.',
componentName,
);
didWarnAboutLegacyWillMount[componentName] = true;
}
}
}
instance.componentWillMount();
Expand Down Expand Up @@ -467,15 +472,17 @@ export default function(
const oldState = instance.state;
if (typeof instance.componentWillReceiveProps === 'function') {
if (__DEV__) {
const componentName = getComponentName(workInProgress) || 'Unknown';
if (!didWarnAboutLegacyWillReceiveProps[componentName]) {
warning(
false,
'%s: componentWillReceiveProps() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillReceiveProps() instead.',
componentName,
);
didWarnAboutLegacyWillReceiveProps[componentName] = true;
if (warnAboutDeprecatedLifecycles) {
const componentName = getComponentName(workInProgress) || 'Unknown';
if (!didWarnAboutLegacyWillReceiveProps[componentName]) {
warning(
false,
'%s: componentWillReceiveProps() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillReceiveProps() instead.',
componentName,
);
didWarnAboutLegacyWillReceiveProps[componentName] = true;
}
}
}

Expand Down Expand Up @@ -814,16 +821,18 @@ export default function(
) {
if (typeof instance.componentWillUpdate === 'function') {
if (__DEV__) {
const componentName =
getComponentName(workInProgress) || 'Component';
if (!didWarnAboutLegacyWillUpdate[componentName]) {
warning(
false,
'%s: componentWillUpdate() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillUpdate() instead.',
componentName,
);
didWarnAboutLegacyWillUpdate[componentName] = true;
if (warnAboutDeprecatedLifecycles) {
const componentName =
getComponentName(workInProgress) || 'Component';
if (!didWarnAboutLegacyWillUpdate[componentName]) {
warning(
false,
'%s: componentWillUpdate() is deprecated and will be removed in the ' +
'next major version. Please use UNSAFE_componentWillUpdate() instead.',
componentName,
);
didWarnAboutLegacyWillUpdate[componentName] = true;
}
}
}

Expand Down
Loading

0 comments on commit 2d9f75d

Please sign in to comment.