[Flight] Set dispatcher for duration of performWork() (#19776)
Joseph Savona committed
Sep 7, 2020 at 19:41 UTC
d38ec17b1d6ab75715c4ec06f2793c2986dcd549
2 files changed
+23
-4
packages/react-server/src/ReactFlightServer.js
+5
-4
@@ -273,11 +273,9 @@ export function resolveModelToJSON(
273
value !== null &&
274
value.$$typeof === REACT_ELEMENT_TYPE
275
) {
276
- const prevDispatcher = ReactCurrentDispatcher.current;
276
// TODO: Concatenate keys of parents onto children.
277
const element: React$Element<any> = (value: any);
278
try {
280
- ReactCurrentDispatcher.current = Dispatcher;
279
// Attempt to render the server component.
280
value = attemptResolveElement(element);
281
} catch (x) {
@@ -292,8 +290,6 @@ export function resolveModelToJSON(
290
// Something errored. Don't bother encoding anything up to here.
291
throw x;
292
}
295
- } finally {
296
- ReactCurrentDispatcher.current = prevDispatcher;
293
}
294
}
295
@@ -355,6 +351,9 @@ function retrySegment(request: Request, segment: Segment): void {
351
}
352
353
function performWork(request: Request): void {
354
+ const prevDispatcher = ReactCurrentDispatcher.current;
355
+ ReactCurrentDispatcher.current = Dispatcher;
356
+
357
const pingedSegments = request.pingedSegments;
358
request.pingedSegments = [];
359
for (let i = 0; i < pingedSegments.length; i++) {
@@ -364,6 +363,8 @@ function performWork(request: Request): void {
363
if (request.flowing) {
364
flushCompletedChunks(request);
365
}
366
+
367
+ ReactCurrentDispatcher.current = prevDispatcher;
368
}
369
370
let reentrant = false;
packages/react-transport-dom-relay/src/__tests__/ReactFlightDOMRelay-test.internal.js
+18
@@ -213,4 +213,22 @@ describe('ReactFlightDOMRelay', () => {
213
},
214
});
215
});
216
+
217
+ it('can handle a subset of Hooks, with element as root', () => {
218
+ const {useMemo, useCallback} = React;
219
+ function Inner({x}) {
220
+ const foo = useMemo(() => x + x, [x]);
221
+ const bar = useCallback(() => 10 + foo, [foo]);
222
+ return bar();
223
+ }
224
+
225
+ function Foo() {
226
+ return <Inner x={2} />;
227
+ }
228
+ const transport = [];
229
+ ReactDOMFlightRelayServer.render(<Foo />, transport);
230
+
231
+ const model = readThrough(transport);
232
+ expect(model).toEqual(14);
233
+ });
234
});