Skip to content

Commit

Permalink
Added unsafe_* lifecycles and deprecation warnings
Browse files Browse the repository at this point in the history
If the old lifecycle hooks (componentWillMount, componentWillUpdate, componentWillReceiveProps) are detected, these methods will be called and a deprecation warning will be logged. (In other words, we do not check for both the presence of the old and new lifecycles.) This commit is expected to fail tests.
  • Loading branch information
bvaughn committed Jan 16, 2018
1 parent 4f309f8 commit e709e30
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 29 deletions.
14 changes: 12 additions & 2 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,18 @@ function resolve(
if (initialState === undefined) {
inst.state = initialState = null;
}
if (inst.componentWillMount) {
inst.componentWillMount();
if (inst.unsafe_componentWillMount || inst.componentWillMount) {
if (inst.componentWillMount) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillMount() instead.',
getComponentName(Component) || 'Unknown',
);
inst.componentWillMount();
} else {
inst.unsafe_componentWillMount();
}
if (queue.length) {
oldQueue = queue;
oldReplace = replace;
Expand Down
81 changes: 66 additions & 15 deletions packages/react-reconciler/src/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,21 @@ export default function(
function callComponentWillMount(workInProgress, instance) {
startPhaseTimer(workInProgress, 'componentWillMount');
const oldState = instance.state;
instance.componentWillMount();

if (typeof instance.componentWillMount === 'function') {
if (__DEV__) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillMount() instead.',
getComponentName(workInProgress),
);
}
instance.componentWillMount();
} else {
instance.unsafe_componentWillMount();
}

stopPhaseTimer();

if (oldState !== instance.state) {
Expand All @@ -415,14 +429,29 @@ export default function(
newProps,
newContext,
) {
startPhaseTimer(workInProgress, 'componentWillReceiveProps');
const oldState = instance.state;
instance.componentWillReceiveProps(newProps, newContext);
stopPhaseTimer();
if (typeof instance.componentWillReceiveProps === 'function') {
if (__DEV__) {
warning(
false,
'%s: componentWillReceiveProps() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillReceiveProps() instead.',
getComponentName(workInProgress),
);
}

// Simulate an async bailout/interruption by invoking lifecycle twice.
if (debugRenderPhaseSideEffects) {
startPhaseTimer(workInProgress, 'componentWillReceiveProps');
instance.componentWillReceiveProps(newProps, newContext);
stopPhaseTimer();
} else {
startPhaseTimer(workInProgress, 'componentWillReceiveProps');
instance.unsafe_componentWillReceiveProps(newProps, newContext);
stopPhaseTimer();

// Simulate an async bailout/interruption by invoking lifecycle twice.
if (debugRenderPhaseSideEffects) {
instance.unsafe_componentWillReceiveProps(newProps, newContext);
}
}

if (instance.state !== oldState) {
Expand Down Expand Up @@ -473,7 +502,10 @@ export default function(
workInProgress.internalContextTag |= AsyncUpdates;
}

if (typeof instance.componentWillMount === 'function') {
if (
typeof instance.unsafe_componentWillMount === 'function' ||
typeof instance.componentWillMount === 'function'
) {
callComponentWillMount(workInProgress, instance);
// If we had additional state updates during this life-cycle, let's
// process them now.
Expand Down Expand Up @@ -619,7 +651,8 @@ export default function(
// during componentDidUpdate we pass the "current" props.

if (
typeof instance.componentWillReceiveProps === 'function' &&
(typeof instance.unsafe_componentWillReceiveProps === 'function' ||
typeof instance.componentWillReceiveProps === 'function') &&
(oldProps !== newProps || oldContext !== newContext)
) {
callComponentWillReceiveProps(
Expand Down Expand Up @@ -679,14 +712,32 @@ export default function(
);

if (shouldUpdate) {
if (typeof instance.componentWillUpdate === 'function') {
startPhaseTimer(workInProgress, 'componentWillUpdate');
instance.componentWillUpdate(newProps, newState, newContext);
stopPhaseTimer();

// Simulate an async bailout/interruption by invoking lifecycle twice.
if (debugRenderPhaseSideEffects) {
if (
typeof instance.unsafe_componentWillUpdate === 'function' ||
typeof instance.componentWillUpdate === 'function'
) {
if (typeof instance.componentWillUpdate === 'function') {
if (__DEV__) {
warning(
false,
'%s: componentWillUpdate() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillUpdate() instead.',
getComponentName(workInProgress),
);
}

startPhaseTimer(workInProgress, 'componentWillUpdate');
instance.componentWillUpdate(newProps, newState, newContext);
stopPhaseTimer();
} else {
startPhaseTimer(workInProgress, 'componentWillUpdate');
instance.unsafe_componentWillUpdate(newProps, newState, newContext);
stopPhaseTimer();

// Simulate an async bailout/interruption by invoking lifecycle twice.
if (debugRenderPhaseSideEffects) {
instance.unsafe_componentWillUpdate(newProps, newState, newContext);
}
}
}
if (typeof instance.componentDidUpdate === 'function') {
Expand Down
66 changes: 54 additions & 12 deletions packages/react-test-renderer/src/ReactShallowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import emptyObject from 'fbjs/lib/emptyObject';
import invariant from 'fbjs/lib/invariant';
import shallowEqual from 'fbjs/lib/shallowEqual';
import checkPropTypes from 'prop-types/checkPropTypes';
import warning from 'fbjs/lib/warning';

class ReactShallowRenderer {
static createRenderer = function() {
Expand Down Expand Up @@ -73,7 +74,7 @@ class ReactShallowRenderer {
this._context = getMaskedContext(element.type.contextTypes, context);

if (this._instance) {
this._updateClassComponent(element.type, element.props, this._context);
this._updateClassComponent(element, this._context);
} else {
if (shouldConstruct(element.type)) {
this._instance = new element.type(
Expand All @@ -96,7 +97,7 @@ class ReactShallowRenderer {
currentlyValidatingElement = null;
}

this._mountClassComponent(element.props, this._context);
this._mountClassComponent(element, this._context);
} else {
this._rendered = element.type(element.props, this._context);
}
Expand All @@ -122,16 +123,31 @@ class ReactShallowRenderer {
this._instance = null;
}

_mountClassComponent(props, context) {
_mountClassComponent(element, context) {
this._instance.context = context;
this._instance.props = props;
this._instance.props = element.props;
this._instance.state = this._instance.state || null;
this._instance.updater = this._updater;

if (typeof this._instance.componentWillMount === 'function') {
if (
typeof this._instance.unsafe_componentWillMount === 'function' ||
typeof this._instance.componentWillMount === 'function'
) {
const beforeState = this._newState;

this._instance.componentWillMount();
if (typeof this._instance.componentWillMount === 'function') {
if (__DEV__) {
warning(
false,
'%s: componentWillMount() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillMount() instead.',
getName(element.type, this._instance),
);
}
this._instance.componentWillMount();
} else {
this._instance.unsafe_componentWillMount();
}

// setState may have been called during cWM
if (beforeState !== this._newState) {
Expand All @@ -144,15 +160,28 @@ class ReactShallowRenderer {
// because DOM refs are not available.
}

_updateClassComponent(type, props, context) {
_updateClassComponent(element, context) {
const {props, type} = element;

const oldState = this._instance.state || emptyObject;
const oldProps = this._instance.props;

if (
oldProps !== props &&
typeof this._instance.componentWillReceiveProps === 'function'
) {
this._instance.componentWillReceiveProps(props, context);
if (oldProps !== props) {
if (typeof this._instance.componentWillReceiveProps === 'function') {
if (__DEV__) {
warning(
false,
'%s: componentWillReceiveProps() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillReceiveProps() instead.',
getName(element.type, this._instance),
);
}
this._instance.componentWillReceiveProps(props, context);
} else if (
typeof this._instance.unsafe_componentWillReceiveProps === 'function'
) {
this._instance.unsafe_componentWillReceiveProps(props, context);
}
}
// Read state after cWRP in case it calls setState
const state = this._newState || oldState;
Expand All @@ -174,7 +203,20 @@ class ReactShallowRenderer {

if (shouldUpdate) {
if (typeof this._instance.componentWillUpdate === 'function') {
if (__DEV__) {
warning(
false,
'%s: componentWillUpdate() is deprecated and will be removed in the ' +
'next major version. Please use unsafe_componentWillUpdate() instead.',
getName(element.type, this._instance),
);
}

this._instance.componentWillUpdate(props, state, context);
} else if (
typeof this._instance.unsafe_componentWillUpdate === 'function'
) {
this._instance.unsafe_componentWillUpdate(props, state, context);
}
}

Expand Down

0 comments on commit e709e30

Please sign in to comment.