@samitouri / QOS-React-2 / commits / 148ffe3cfe

Failing test for Client reconciliation (#20318)

Dan Abramov committed Dec 1, 2020 at 16:40 UTC 148ffe3cfe7a2627bebfb1852f332a1d122b3103
1 file changed +88
packages/react-transport-dom-webpack/src/__tests__/ReactFlightDOM-test.js
+88
@@ -440,4 +440,92 @@ describe('ReactFlightDOM', () => {
440 '<p>Game over</p>', // TODO: should not have message in prod.
441 );
442 });
443 +
444 + // @gate experimental
445 + it('should preserve state of client components on refetch', async () => {
446 + const {Suspense} = React;
447 +
448 + // Client
449 +
450 + function Page({response}) {
451 + return response.readRoot();
452 + }
453 +
454 + function Input() {
455 + return <input />;
456 + }
457 +
458 + const InputClient = moduleReference(Input);
459 +
460 + // Server
461 +
462 + function App({color}) {
463 + // Verify both DOM and Client children.
464 + return (
465 + <div style={{color}}>
466 + <input />
467 + <InputClient />
468 + </div>
469 + );
470 + }
471 +
472 + const container = document.createElement('div');
473 + const root = ReactDOM.unstable_createRoot(container);
474 +
475 + const stream1 = getTestStream();
476 + ReactTransportDOMServer.pipeToNodeWritable(
477 + <App color="red" />,
478 + stream1.writable,
479 + webpackMap,
480 + );
481 + const response1 = ReactTransportDOMClient.createFromReadableStream(
482 + stream1.readable,
483 + );
484 + await act(async () => {
485 + root.render(
486 + <Suspense fallback={<p>(loading)</p>}>
487 + <Page response={response1} />
488 + </Suspense>,
489 + );
490 + });
491 + expect(container.children.length).toBe(1);
492 + expect(container.children[0].tagName).toBe('DIV');
493 + expect(container.children[0].style.color).toBe('red');
494 +
495 + // Change the DOM state for both inputs.
496 + const inputA = container.children[0].children[0];
497 + expect(inputA.tagName).toBe('INPUT');
498 + inputA.value = 'hello';
499 + const inputB = container.children[0].children[1];
500 + expect(inputB.tagName).toBe('INPUT');
501 + inputB.value = 'goodbye';
502 +
503 + const stream2 = getTestStream();
504 + ReactTransportDOMServer.pipeToNodeWritable(
505 + <App color="blue" />,
506 + stream2.writable,
507 + webpackMap,
508 + );
509 + const response2 = ReactTransportDOMClient.createFromReadableStream(
510 + stream2.readable,
511 + );
512 + await act(async () => {
513 + root.render(
514 + <Suspense fallback={<p>(loading)</p>}>
515 + <Page response={response2} />
516 + </Suspense>,
517 + );
518 + });
519 + expect(container.children.length).toBe(1);
520 + expect(container.children[0].tagName).toBe('DIV');
521 + expect(container.children[0].style.color).toBe('blue');
522 +
523 + // Verify we didn't destroy the DOM for either input.
524 + expect(inputA === container.children[0].children[0]).toBe(true);
525 + expect(inputA.tagName).toBe('INPUT');
526 + expect(inputA.value).toBe('hello');
527 + expect(inputB === container.children[0].children[1]).toBe(true);
528 + expect(inputB.tagName).toBe('INPUT');
529 + expect(inputB.value).toBe('goodbye');
530 + });
531 });