Use ReactDebugLifeCycle to track if we're inside getChildContext

This commit is contained in:
Andrew Clark
2017-02-24 11:02:21 -08:00
parent 309dea5b4c
commit d2c28be69b
3 changed files with 28 additions and 43 deletions
+11 -24
View File
@@ -35,6 +35,7 @@ const {
if (__DEV__) {
var checkReactTypeSpec = require('checkReactTypeSpec');
var ReactDebugCurrentFrame = require('ReactDebugCurrentFrame');
var ReactDebugLifeCycle = require('ReactDebugLifeCycle');
var warnedAboutMissingGetChildContext = {};
}
@@ -47,21 +48,6 @@ let didPerformWorkStackCursor : StackCursor<boolean> = createCursor(false);
// pushed the next context provider, and now need to merge their contexts.
let previousContext : Object = emptyObject;
if (__DEV__) {
var _isProcessingChildContext = false;
var onBeginProcessingChildContext = function() {
_isProcessingChildContext = true;
};
exports.onBeginProcessingChildContext = onBeginProcessingChildContext;
var onEndProcessingChildContext = function() {
_isProcessingChildContext = false;
};
exports.onEndProcessingChildContext = onEndProcessingChildContext;
exports.isProcessingChildContext = function() : boolean {
return _isProcessingChildContext;
};
}
function getUnmaskedContext(workInProgress : Fiber) : Object {
const hasOwnContext = isContextProvider(workInProgress);
if (hasOwnContext) {
@@ -159,10 +145,6 @@ exports.pushTopLevelContextObject = function(fiber : Fiber, context : Object, di
};
function processChildContext(fiber : Fiber, parentContext : Object, isReconciling : boolean): Object {
if (__DEV__) {
onBeginProcessingChildContext();
}
const instance = fiber.stateNode;
const childContextTypes = fiber.type.childContextTypes;
@@ -187,7 +169,16 @@ function processChildContext(fiber : Fiber, parentContext : Object, isReconcilin
return parentContext;
}
const childContext = instance.getChildContext();
let childContext;
if (__DEV__) {
ReactDebugLifeCycle.current = fiber;
ReactDebugLifeCycle.phase = 'getChildContext';
childContext = instance.getChildContext();
ReactDebugLifeCycle.current = null;
ReactDebugLifeCycle.phase = null;
} else {
childContext = instance.getChildContext();
}
for (let contextKey in childContext) {
invariant(
contextKey in childContextTypes,
@@ -209,10 +200,6 @@ function processChildContext(fiber : Fiber, parentContext : Object, isReconcilin
ReactDebugCurrentFrame.current = null;
}
if (__DEV__) {
onEndProcessingChildContext();
}
return {...parentContext, ...childContext};
}
exports.processChildContext = processChildContext;
@@ -91,10 +91,6 @@ if (__DEV__) {
var ReactFiberInstrumentation = require('ReactFiberInstrumentation');
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
var ReactDebugLifeCycle = require('ReactDebugLifeCycle');
var {
isProcessingChildContext,
onEndProcessingChildContext,
} = require('ReactFiberContext');
var warnAboutUpdateOnUnmounted = function(instance : ReactClass<any>) {
const ctor = instance.constructor;
@@ -109,19 +105,22 @@ if (__DEV__) {
};
var warnAboutInvalidUpdates = function(instance : ReactClass<any>) {
if (isProcessingChildContext()) {
warning(
false,
'setState(...): Cannot call setState() inside getChildContext()',
);
} else if (ReactDebugLifeCycle.phase === 'render') {
warning(
false,
'Cannot update during an existing state transition (such as within ' +
'`render` or another component\'s constructor). Render methods should ' +
'be a pure function of props and state; constructor side-effects are ' +
'an anti-pattern, but can be moved to `componentWillMount`.'
);
switch (ReactDebugLifeCycle.phase) {
case 'getChildContext':
warning(
false,
'setState(...): Cannot call setState() inside getChildContext()',
);
break;
case 'render':
warning(
false,
'Cannot update during an existing state transition (such as within ' +
'`render` or another component\'s constructor). Render methods should ' +
'be a pure function of props and state; constructor side-effects are ' +
'an anti-pattern, but can be moved to `componentWillMount`.'
);
break;
}
};
}
@@ -883,7 +882,6 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
ReactDebugCurrentFiber.current = null;
ReactDebugLifeCycle.current = null;
ReactDebugLifeCycle.phase = null;
onEndProcessingChildContext();
}
// It is no longer valid because this unit of work failed.
nextUnitOfWork = null;
@@ -14,7 +14,7 @@
import type { Fiber } from 'ReactFiber';
type LifeCyclePhase = 'render';
type LifeCyclePhase = 'render' | 'getChildContext';
const ReactDebugLifeCycle = {
current: (null : Fiber | null),