@samitouri / QOS-React-2 / commits / d38ec17b1d

[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 });