Skip to content

Commit fe9e602

Browse files
committed
Unify context implementations
Implements the legacy, string-based context API on top of the new context API. This doesn't save much in code size because most of the legacy stuff deals with merging and masking. Arguably, it's a conceptual complexity win. I'm ambivalent about whether we land this.
1 parent f2670bf commit fe9e602

10 files changed

+417
-423
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 208 additions & 104 deletions
Large diffs are not rendered by default.

packages/react-reconciler/src/ReactFiberClassComponent.js

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,7 @@ import {
3737
ForceUpdate,
3838
} from './ReactUpdateQueue';
3939
import {NoWork} from './ReactFiberExpirationTime';
40-
import {
41-
cacheContext,
42-
getMaskedContext,
43-
getUnmaskedContext,
44-
isContextConsumer,
45-
hasContextChanged,
46-
emptyContextObject,
47-
} from './ReactFiberContext';
40+
// TODO: Maybe we can remove this?
4841
import {
4942
requestCurrentTime,
5043
computeExpirationForFiber,
@@ -468,14 +461,10 @@ function adoptClassInstance(workInProgress: Fiber, instance: any): void {
468461
function constructClassInstance(
469462
workInProgress: Fiber,
470463
props: any,
464+
legacyContext: Object,
471465
renderExpirationTime: ExpirationTime,
472466
): any {
473467
const ctor = workInProgress.type;
474-
const unmaskedContext = getUnmaskedContext(workInProgress);
475-
const needsContext = isContextConsumer(workInProgress);
476-
const context = needsContext
477-
? getMaskedContext(workInProgress, unmaskedContext)
478-
: emptyContextObject;
479468

480469
// Instantiate twice to help detect side-effects.
481470
if (__DEV__) {
@@ -484,11 +473,11 @@ function constructClassInstance(
484473
(debugRenderPhaseSideEffectsForStrictMode &&
485474
workInProgress.mode & StrictMode)
486475
) {
487-
new ctor(props, context); // eslint-disable-line no-new
476+
new ctor(props, legacyContext); // eslint-disable-line no-new
488477
}
489478
}
490479

491-
const instance = new ctor(props, context);
480+
const instance = new ctor(props, legacyContext);
492481
const state = (workInProgress.memoizedState =
493482
instance.state !== null && instance.state !== undefined
494483
? instance.state
@@ -577,12 +566,6 @@ function constructClassInstance(
577566
}
578567
}
579568

580-
// Cache unmasked context so we can avoid recreating masked context unless necessary.
581-
// ReactFiberContext usually updates this cache but can't for newly-created instances.
582-
if (needsContext) {
583-
cacheContext(workInProgress, unmaskedContext, context);
584-
}
585-
586569
return instance;
587570
}
588571

@@ -650,6 +633,7 @@ function callComponentWillReceiveProps(
650633
// Invokes the mount life-cycles on a previously never rendered instance.
651634
function mountClassInstance(
652635
workInProgress: Fiber,
636+
legacyContext: Object,
653637
renderExpirationTime: ExpirationTime,
654638
): void {
655639
const ctor = workInProgress.type;
@@ -660,12 +644,11 @@ function mountClassInstance(
660644

661645
const instance = workInProgress.stateNode;
662646
const props = workInProgress.pendingProps;
663-
const unmaskedContext = getUnmaskedContext(workInProgress);
664647

665648
instance.props = props;
666649
instance.state = workInProgress.memoizedState;
667650
instance.refs = emptyRefsObject;
668-
instance.context = getMaskedContext(workInProgress, unmaskedContext);
651+
instance.context = legacyContext;
669652

670653
if (__DEV__) {
671654
if (workInProgress.mode & StrictMode) {
@@ -737,6 +720,7 @@ function mountClassInstance(
737720

738721
function resumeMountClassInstance(
739722
workInProgress: Fiber,
723+
nextLegacyContext: Object,
740724
renderExpirationTime: ExpirationTime,
741725
): boolean {
742726
const ctor = workInProgress.type;
@@ -747,13 +731,8 @@ function resumeMountClassInstance(
747731
instance.props = oldProps;
748732

749733
const oldContext = instance.context;
750-
const nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress);
751-
const nextLegacyContext = getMaskedContext(
752-
workInProgress,
753-
nextLegacyUnmaskedContext,
754-
);
755734

756-
const hasPendingNewContext = checkForPendingContext(
735+
const hasPendingContext = checkForPendingContext(
757736
workInProgress,
758737
renderExpirationTime,
759738
);
@@ -802,8 +781,7 @@ function resumeMountClassInstance(
802781
if (
803782
oldProps === newProps &&
804783
oldState === newState &&
805-
!hasContextChanged() &&
806-
!hasPendingNewContext &&
784+
!hasPendingContext &&
807785
!checkHasForceUpdateAfterProcessing()
808786
) {
809787
// If an update was already in progress, we should schedule an Update
@@ -825,7 +803,6 @@ function resumeMountClassInstance(
825803

826804
const shouldUpdate =
827805
checkHasForceUpdateAfterProcessing() ||
828-
hasPendingNewContext ||
829806
checkShouldComponentUpdate(
830807
workInProgress,
831808
oldProps,
@@ -881,6 +858,7 @@ function resumeMountClassInstance(
881858
function updateClassInstance(
882859
current: Fiber,
883860
workInProgress: Fiber,
861+
nextLegacyContext: Object,
884862
renderExpirationTime: ExpirationTime,
885863
): boolean {
886864
const ctor = workInProgress.type;
@@ -891,13 +869,8 @@ function updateClassInstance(
891869
instance.props = oldProps;
892870

893871
const oldContext = instance.context;
894-
const nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress);
895-
const nextLegacyContext = getMaskedContext(
896-
workInProgress,
897-
nextLegacyUnmaskedContext,
898-
);
899872

900-
const hasPendingNewContext = checkForPendingContext(
873+
const hasPendingContext = checkForPendingContext(
901874
workInProgress,
902875
renderExpirationTime,
903876
);
@@ -947,8 +920,7 @@ function updateClassInstance(
947920
if (
948921
oldProps === newProps &&
949922
oldState === newState &&
950-
!hasContextChanged() &&
951-
!hasPendingNewContext &&
923+
!hasPendingContext &&
952924
!checkHasForceUpdateAfterProcessing()
953925
) {
954926
// If an update was already in progress, we should schedule an Update
@@ -983,7 +955,6 @@ function updateClassInstance(
983955

984956
const shouldUpdate =
985957
checkHasForceUpdateAfterProcessing() ||
986-
hasPendingNewContext ||
987958
checkShouldComponentUpdate(
988959
workInProgress,
989960
oldProps,

packages/react-reconciler/src/ReactFiberCompleteWork.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,7 @@ import {
6161
popHostContainer,
6262
} from './ReactFiberHostContext';
6363
import {recordElapsedActualRenderTime} from './ReactProfilerTimer';
64-
import {
65-
popContextProvider as popLegacyContextProvider,
66-
popTopLevelContextObject as popTopLevelLegacyContextObject,
67-
} from './ReactFiberContext';
64+
import {popLegacyContext, popRootLegacyContext} from './ReactFiberContext';
6865
import {popProvider} from './ReactFiberNewContext';
6966
import {
7067
prepareToHydrateHostInstance,
@@ -325,12 +322,12 @@ function completeWork(
325322
return null;
326323
case ClassComponent: {
327324
// We are leaving this subtree, so pop context if any.
328-
popLegacyContextProvider(workInProgress);
325+
popLegacyContext(workInProgress);
329326
return null;
330327
}
331328
case HostRoot: {
332329
popHostContainer(workInProgress);
333-
popTopLevelLegacyContextObject(workInProgress);
330+
popRootLegacyContext(workInProgress);
334331
const fiberRoot = (workInProgress.stateNode: FiberRoot);
335332
if (fiberRoot.pendingContext) {
336333
fiberRoot.context = fiberRoot.pendingContext;

0 commit comments

Comments
 (0)