Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4aaae58

Browse files
committedDec 14, 2017
Store nearest provider on context object
1 parent 7761a51 commit 4aaae58

File tree

5 files changed

+29
-31
lines changed

5 files changed

+29
-31
lines changed
 

‎packages/react-dom/src/server/ReactPartialRenderer.js

+13-16
Original file line numberDiff line numberDiff line change
@@ -124,33 +124,30 @@ if (__DEV__) {
124124
}
125125

126126
// Context (new API)
127-
let providerStack: Array<ReactProvider<mixed>> = []; // Stack of provider objects
127+
let providerStack: Array<ReactProvider<any>> = []; // Stack of provider objects
128128
let index = -1;
129129

130130
export function pushProvider<T>(provider: ReactProvider<T>): void {
131131
index += 1;
132132
providerStack[index] = provider;
133+
const context: ReactContext<any> = provider.type.context;
134+
context.currentProvider = provider;
133135
}
134136

135137
export function popProvider<T>(provider: ReactProvider<T>): void {
136138
if (__DEV__) {
137139
warning(index > -1 && provider === providerStack[index], 'Unexpected pop.');
138140
}
141+
// $FlowFixMe - Intentionally unsound
139142
providerStack[index] = null;
140143
index -= 1;
141-
}
142-
143-
// Find the nearest matching provider
144-
export function getProvider<T>(
145-
context: ReactContext<T>,
146-
): ReactProvider<T> | null {
147-
for (let i = index; i > -1; i--) {
148-
const provider = providerStack[i];
149-
if (provider.type.context === context) {
150-
return provider;
151-
}
144+
const context: ReactContext<any> = provider.type.context;
145+
if (index < 0) {
146+
context.currentProvider = null;
147+
} else {
148+
const previousProvider = providerStack[index];
149+
context.currentProvider = previousProvider;
152150
}
153-
return null;
154151
}
155152

156153
let didWarnDefaultInputValue = false;
@@ -731,7 +728,7 @@ class ReactDOMServerRenderer {
731728
if (typeof elementType === 'object' && elementType !== null) {
732729
switch (elementType.$$typeof) {
733730
case REACT_PROVIDER_TYPE: {
734-
const provider: ReactProvider<any> = nextChild;
731+
const provider: ReactProvider<any> = (nextChild: any);
735732
const nextProps = provider.props;
736733
const nextChildren = toArray(nextProps.children);
737734
const frame: Frame = {
@@ -752,10 +749,10 @@ class ReactDOMServerRenderer {
752749
return '';
753750
}
754751
case REACT_CONSUMER_TYPE: {
755-
const consumer: ReactConsumer<any> = nextChild;
752+
const consumer: ReactConsumer<any> = (nextChild: any);
756753
const nextProps = consumer.props;
757754

758-
const provider = getProvider(consumer.type.context);
755+
const provider = consumer.type.context.currentProvider;
759756
let nextValue;
760757
if (provider === null) {
761758
// Detached consumer

‎packages/react-reconciler/src/ReactFiberBeginWork.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import {
6666
pushTopLevelContextObject,
6767
invalidateContextProvider,
6868
} from './ReactFiberContext';
69-
import {pushProvider, getProvider} from './ReactFiberNewContext';
69+
import {pushProvider} from './ReactFiberNewContext';
7070
import {NoWork, Never} from './ReactFiberExpirationTime';
7171

7272
let warnedAboutStatelessRefs;
@@ -755,7 +755,7 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
755755
const oldProps = workInProgress.memoizedProps;
756756

757757
// Get the nearest ancestor provider.
758-
const providerFiber: Fiber | null = getProvider(context);
758+
const providerFiber: Fiber | null = context.currentProvider;
759759

760760
let newValue;
761761
let valueDidChange;

‎packages/react-reconciler/src/ReactFiberNewContext.js

+12-11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ let index = -1;
1818
export function pushProvider(providerFiber: Fiber): void {
1919
index += 1;
2020
stack[index] = providerFiber;
21+
const context: ReactContext<any> = providerFiber.type.context;
22+
context.currentProvider = providerFiber;
2123
}
2224

2325
export function popProvider(providerFiber: Fiber): void {
@@ -26,21 +28,20 @@ export function popProvider(providerFiber: Fiber): void {
2628
}
2729
stack[index] = null;
2830
index -= 1;
29-
}
30-
31-
// Find the nearest matching provider
32-
export function getProvider<T>(context: ReactContext<T>): Fiber | null {
33-
for (let i = index; i > -1; i--) {
34-
const provider = stack[i];
35-
if (provider.type.context === context) {
36-
return provider;
37-
}
31+
const context: ReactContext<any> = providerFiber.type.context;
32+
if (index < 0) {
33+
context.currentProvider = null;
34+
} else {
35+
const previousProviderFiber = stack[index];
36+
context.currentProvider = previousProviderFiber;
3837
}
39-
return null;
4038
}
4139

4240
export function resetProviderStack(): void {
4341
for (let i = index; i > -1; i--) {
44-
stack[i] = null;
42+
const providerFiber = stack[i];
43+
const context: ReactContext<any> = providerFiber.type.context;
44+
context.currentProvider = null;
45+
stack[i] = undefined;
4546
}
4647
}

‎packages/shared/ReactContext.js

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function createContext<T>(defaultValue: T): ReactContext<T> {
5353
};
5454
},
5555
defaultValue,
56+
currentProvider: null,
5657
};
5758

5859
providerType = {

‎packages/shared/ReactTypes.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import {Symbol} from './node_modules/typescript/lib/typescript';
2-
31
/**
42
* Copyright (c) 2014-present, Facebook, Inc.
53
*
@@ -88,6 +86,7 @@ export type ReactContext<T> = {
8886
provide(value: T, children: ReactNodeList, key?: string): ReactProvider<T>,
8987
consume(render: (value: T) => ReactNodeList, key?: string): ReactConsumer<T>,
9088
defaultValue: T,
89+
currentProvider: any, // Fiber | null
9190
};
9291

9392
export type ReactPortal = {

0 commit comments

Comments
 (0)
Please sign in to comment.