Skip to content

Commit 24b8ba7

Browse files
authored
Merge pull request #8723 from bvaughn/improve-unmasked-context-caching
Improve unmasked context caching
2 parents f1a49e8 + e5a7b75 commit 24b8ba7

2 files changed

Lines changed: 25 additions & 5 deletions

File tree

src/renderers/shared/fiber/ReactFiberClassComponent.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ import type { Fiber } from 'ReactFiber';
1616
import type { PriorityLevel } from 'ReactPriorityLevel';
1717

1818
var {
19+
cacheContext,
1920
getMaskedContext,
2021
getUnmaskedContext,
22+
isContextConsumer,
2123
} = require('ReactFiberContext');
2224
var {
2325
addUpdate,
@@ -28,6 +30,7 @@ var {
2830
var { hasContextChanged } = require('ReactFiberContext');
2931
var { getComponentName, isMounted } = require('ReactFiberTreeReflection');
3032
var ReactInstanceMap = require('ReactInstanceMap');
33+
var emptyObject = require('emptyObject');
3134
var shallowEqual = require('shallowEqual');
3235
var warning = require('warning');
3336
var invariant = require('invariant');
@@ -206,15 +209,17 @@ module.exports = function(
206209
const ctor = workInProgress.type;
207210
const props = workInProgress.pendingProps;
208211
const unmaskedContext = getUnmaskedContext(workInProgress);
209-
const context = getMaskedContext(workInProgress, unmaskedContext);
212+
const needsContext = isContextConsumer(workInProgress);
213+
const context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject;
210214
const instance = new ctor(props, context);
211215
adoptClassInstance(workInProgress, instance);
212216
checkClassInstance(workInProgress);
213217

214218
// Cache unmasked context so we can avoid recreating masked context unless necessary.
215219
// ReactFiberContext usually updates this cache but can't for newly-created instances.
216-
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
217-
instance.__reactInternalMemoizedMaskedChildContext = context;
220+
if (needsContext) {
221+
cacheContext(workInProgress, unmaskedContext, context);
222+
}
218223

219224
return instance;
220225
}

src/renderers/shared/fiber/ReactFiberContext.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ function getUnmaskedContext(workInProgress : Fiber) : Object {
5757
}
5858
exports.getUnmaskedContext = getUnmaskedContext;
5959

60+
function cacheContext(workInProgress : Fiber, unmaskedContext : Object, maskedContext : Object) {
61+
const instance = workInProgress.stateNode;
62+
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
63+
instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
64+
}
65+
exports.cacheContext = cacheContext;
66+
6067
exports.getMaskedContext = function(workInProgress : Fiber, unmaskedContext : Object) {
6168
const type = workInProgress.type;
6269
const contextTypes = type.contextTypes;
@@ -86,9 +93,9 @@ exports.getMaskedContext = function(workInProgress : Fiber, unmaskedContext : Ob
8693
}
8794

8895
// Cache unmasked context so we can avoid recreating masked context unless necessary.
96+
// Context is created before the class component is instantiated so check for instance.
8997
if (instance) {
90-
instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
91-
instance.__reactInternalMemoizedMaskedChildContext = context;
98+
cacheContext(workInProgress, unmaskedContext, context);
9299
}
93100

94101
return context;
@@ -98,6 +105,14 @@ exports.hasContextChanged = function() : boolean {
98105
return didPerformWorkStackCursor.current;
99106
};
100107

108+
function isContextConsumer(fiber : Fiber) : boolean {
109+
return (
110+
fiber.tag === ClassComponent &&
111+
fiber.type.contextTypes != null
112+
);
113+
}
114+
exports.isContextConsumer = isContextConsumer;
115+
101116
function isContextProvider(fiber : Fiber) : boolean {
102117
return (
103118
fiber.tag === ClassComponent &&

0 commit comments

Comments
 (0)