Skip to content

Commit

Permalink
Use ReactDebugLifeCycle to track if we're inside getChildContext
Browse files Browse the repository at this point in the history
  • Loading branch information
acdlite committed Feb 22, 2017
1 parent 9a4de8d commit 76233b8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 44 deletions.
35 changes: 11 additions & 24 deletions src/renderers/shared/fiber/ReactFiberContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const {

if (__DEV__) {
var checkReactTypeSpec = require('checkReactTypeSpec');
var ReactDebugLifeCycle = require('ReactDebugLifeCycle');
var warnedAboutMissingGetChildContext = {};
}

Expand All @@ -46,21 +47,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) {
Expand Down Expand Up @@ -156,10 +142,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;

Expand All @@ -184,7 +166,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,
Expand All @@ -204,10 +195,6 @@ function processChildContext(fiber : Fiber, parentContext : Object, isReconcilin
checkReactTypeSpec(childContextTypes, childContext, 'childContext', name, null, workInProgress);
}

if (__DEV__) {
onEndProcessingChildContext();
}

return {...parentContext, ...childContext};
}
exports.processChildContext = processChildContext;
Expand Down
36 changes: 17 additions & 19 deletions src/renderers/shared/fiber/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,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;
Expand All @@ -108,19 +104,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;
}
};
}
Expand Down Expand Up @@ -784,7 +783,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
} catch (error) {
// We caught an error during either the begin or complete phases.
const failedWork = nextUnitOfWork;

if (failedWork !== null) {
// Reset the priority context to its value before reconciliation.
priorityContext = priorityContextBeforeReconciliation;
Expand Down Expand Up @@ -882,7 +881,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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import type { Fiber } from 'ReactFiber';

type LifeCyclePhase = 'render';
type LifeCyclePhase = 'render' | 'getChildContext';

const ReactDebugLifeCycle = {
current: (null : Fiber | null),
Expand Down

0 comments on commit 76233b8

Please sign in to comment.