Merge pull request #8723 from bvaughn/improve-unmasked-context-caching

Improve unmasked context caching
This commit is contained in:
Brian Vaughn
2017-01-09 15:33:20 -08:00
committed by GitHub
2 changed files with 25 additions and 5 deletions
@@ -16,8 +16,10 @@ import type { Fiber } from 'ReactFiber';
import type { PriorityLevel } from 'ReactPriorityLevel';
var {
cacheContext,
getMaskedContext,
getUnmaskedContext,
isContextConsumer,
} = require('ReactFiberContext');
var {
addUpdate,
@@ -28,6 +30,7 @@ var {
var { hasContextChanged } = require('ReactFiberContext');
var { getComponentName, isMounted } = require('ReactFiberTreeReflection');
var ReactInstanceMap = require('ReactInstanceMap');
var emptyObject = require('emptyObject');
var shallowEqual = require('shallowEqual');
var warning = require('warning');
var invariant = require('invariant');
@@ -206,15 +209,17 @@ module.exports = function(
const ctor = workInProgress.type;
const props = workInProgress.pendingProps;
const unmaskedContext = getUnmaskedContext(workInProgress);
const context = getMaskedContext(workInProgress, unmaskedContext);
const needsContext = isContextConsumer(workInProgress);
const context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject;
const instance = new ctor(props, context);
adoptClassInstance(workInProgress, instance);
checkClassInstance(workInProgress);
// Cache unmasked context so we can avoid recreating masked context unless necessary.
// ReactFiberContext usually updates this cache but can't for newly-created instances.
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
instance.__reactInternalMemoizedMaskedChildContext = context;
if (needsContext) {
cacheContext(workInProgress, unmaskedContext, context);
}
return instance;
}
@@ -57,6 +57,13 @@ function getUnmaskedContext(workInProgress : Fiber) : Object {
}
exports.getUnmaskedContext = getUnmaskedContext;
function cacheContext(workInProgress : Fiber, unmaskedContext : Object, maskedContext : Object) {
const instance = workInProgress.stateNode;
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
}
exports.cacheContext = cacheContext;
exports.getMaskedContext = function(workInProgress : Fiber, unmaskedContext : Object) {
const type = workInProgress.type;
const contextTypes = type.contextTypes;
@@ -86,9 +93,9 @@ exports.getMaskedContext = function(workInProgress : Fiber, unmaskedContext : Ob
}
// Cache unmasked context so we can avoid recreating masked context unless necessary.
// Context is created before the class component is instantiated so check for instance.
if (instance) {
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
instance.__reactInternalMemoizedMaskedChildContext = context;
cacheContext(workInProgress, unmaskedContext, context);
}
return context;
@@ -98,6 +105,14 @@ exports.hasContextChanged = function() : boolean {
return didPerformWorkStackCursor.current;
};
function isContextConsumer(fiber : Fiber) : boolean {
return (
fiber.tag === ClassComponent &&
fiber.type.contextTypes != null
);
}
exports.isContextConsumer = isContextConsumer;
function isContextProvider(fiber : Fiber) : boolean {
return (
fiber.tag === ClassComponent &&