@@ -57,14 +57,16 @@ export function preload(element) {
57
57
* @kind function
58
58
* @name preload~recursePreload
59
59
* @param {ReactElement } rootElement A React virtual DOM element.
60
- * @param {Object } [rootLegacyContext={}] Legacy React context for the root element and children.
60
+ * @param {Object } [rootLegacyContext={}] React legacy context for the root element and children.
61
+ * @param {Object } [rootNewContext={}] React new context map for the root element and children.
61
62
* @param {boolean } [loadRoot=true] Should the root element be loaded.
62
63
* @returns {Promise } Resolves once loading is done.
63
64
* @ignore
64
65
*/
65
66
const recursePreload = (
66
67
rootElement ,
67
68
rootLegacyContext = { } ,
69
+ rootNewContext = new Map ( ) ,
68
70
loadRoot = true
69
71
) => {
70
72
const loading = [ ]
@@ -73,14 +75,15 @@ export function preload(element) {
73
75
* @kind function
74
76
* @name preload~recursePreload~recurse
75
77
* @param {ReactElement } element A React virtual DOM element.
76
- * @param {Object } [legacyContext] Legacy React context for the element and children.
78
+ * @param {Object } [legacyContext] React legacy context for the element and children.
79
+ * @param {Map } [newContext] React new context map for the element and children.
77
80
* @ignore
78
81
*/
79
- const recurse = ( element , legacyContext ) => {
82
+ const recurse = ( element , legacyContext , newContext ) => {
80
83
if ( ! element ) return
81
84
82
85
if ( Array . isArray ( element ) ) {
83
- element . forEach ( item => recurse ( item , legacyContext ) )
86
+ element . forEach ( item => recurse ( item , legacyContext , newContext ) )
84
87
return
85
88
}
86
89
@@ -94,13 +97,19 @@ export function preload(element) {
94
97
// Determine the component props.
95
98
const props = { ...element . type . defaultProps , ...element . props }
96
99
97
- if ( element . type . $$typeof === REACT_CONTEXT_TYPE )
100
+ if ( element . type . $$typeof === REACT_CONTEXT_TYPE ) {
98
101
// Context consumer element.
99
- recurse (
100
- element . props . children ( element . type . _context . currentValue ) ,
101
- legacyContext
102
- )
103
- else if (
102
+
103
+ let value = element . type . _currentValue
104
+ const Provider = element . type . _context
105
+ ? element . type . _context . Provider
106
+ : element . type . Provider
107
+
108
+ if ( newContext && newContext . has ( Provider ) )
109
+ value = newContext . get ( Provider )
110
+
111
+ recurse ( element . props . children ( value ) , legacyContext , newContext )
112
+ } else if (
104
113
// The element is a class component…
105
114
element . type . prototype &&
106
115
( element . type . prototype . isReactComponent ||
@@ -144,28 +153,34 @@ export function preload(element) {
144
153
// Load this query.
145
154
instance . load ( ) . then ( ( ) =>
146
155
// Preload children, without reloading this query as the root.
147
- recursePreload ( element , legacyContext , false )
156
+ recursePreload ( element , legacyContext , newContext , false )
148
157
)
149
158
)
150
- else recurse ( instance . render ( ) , legacyContext )
159
+ else recurse ( instance . render ( ) , legacyContext , newContext )
151
160
}
152
161
// The element is a functional component…
153
- else recurse ( element . type ( props ) , legacyContext )
162
+ else recurse ( element . type ( props ) , legacyContext , newContext )
154
163
} else if (
155
164
// The element is a context provider or DOM element and…
156
165
element . props &&
157
166
// …It has children…
158
167
element . props . children
159
168
) {
160
169
// If the element is a context provider first set the value.
161
- if ( element . type . _context )
162
- element . type . _context . currentValue = element . props . value
170
+ if ( element . type . _context ) {
171
+ // Clone the context map to scope mutations to this provider’s
172
+ // descendants.
173
+ newContext = new Map ( newContext )
174
+
175
+ // Set the context, keyed by the provider’s component type.
176
+ newContext . set ( element . type , element . props . value )
177
+ }
163
178
164
- recurse ( element . props . children , legacyContext )
179
+ recurse ( element . props . children , legacyContext , newContext )
165
180
}
166
181
}
167
182
168
- recurse ( rootElement , rootLegacyContext )
183
+ recurse ( rootElement , rootLegacyContext , rootNewContext )
169
184
170
185
return Promise . all ( loading )
171
186
}
0 commit comments