Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e709e30
Added unsafe_* lifecycles and deprecation warnings
bvaughn Jan 16, 2018
404944e
Ran lifecycle hook codemod over project
bvaughn Jan 16, 2018
bd300b3
Manually migrated CoffeeScript and TypeScript tests
bvaughn Jan 16, 2018
2868176
Added inline note to createReactClassIntegration-test
bvaughn Jan 16, 2018
8679926
Udated NativeMethodsMixin with new lifecycle hooks
bvaughn Jan 16, 2018
64f27d7
Added static getDerivedStateFromProps to ReactPartialRenderer
bvaughn Jan 17, 2018
1047182
Added getDerivedStateFromProps to shallow renderer
bvaughn Jan 17, 2018
035c220
Dedupe and DEV-only deprecation warning in server renderer
bvaughn Jan 17, 2018
8d0e001
Renamed unsafe_* prefix to UNSAFE_* to be more noticeable
bvaughn Jan 17, 2018
b71ca93
Added getDerivedStateFromProps to ReactFiberClassComponent
bvaughn Jan 17, 2018
09c39d0
Warn about UNSAFE_componentWillRecieveProps misspelling
bvaughn Jan 17, 2018
286df77
Added tests to createReactClassIntegration for new lifecycles
bvaughn Jan 17, 2018
b699543
Added warning for stateless functional components with gDSFP
bvaughn Jan 17, 2018
68f2fe7
Added createReactClass test for static gDSFP
bvaughn Jan 18, 2018
2d9f75d
Moved lifecycle deprecation warnings behind (disabled) feature flag
bvaughn Jan 18, 2018
8f125b7
Tidying up
bvaughn Jan 18, 2018
1d3e3d5
Merge branch 'master' into rfc-6
bvaughn Jan 18, 2018
d95ec49
Tweaked warning message wording slightly
bvaughn Jan 18, 2018
b940938
Replaced truthy partialState checks with != null
bvaughn Jan 18, 2018
6cd0a8e
Call getDerivedStateFromProps via .call(null) to prevent type access
bvaughn Jan 18, 2018
7572667
Move shallow-renderer didWarn* maps off the instance
bvaughn Jan 18, 2018
361a2cf
Only call getDerivedStateFromProps if props instance has changed
bvaughn Jan 18, 2018
8178d52
Avoid creating new state object if not necessary
bvaughn Jan 18, 2018
8d67e27
Inject state as a param to callGetDerivedStateFromProps
bvaughn Jan 18, 2018
53770c3
Explicitly warn about uninitialized state before calling getDerivedSt…
bvaughn Jan 18, 2018
3772ee2
Improved wording for deprecation lifecycle warnings
bvaughn Jan 18, 2018
4dfa6e1
Merge branch 'master' into rfc-6
bvaughn Jan 18, 2018
5609031
Fix state-regression for module-pattern components
bvaughn Jan 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added unsafe_* lifecycles and deprecation warnings
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
commit e709e30dda6cbea64ab20ab41d3e985af6bf4ca6
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