From 39734ee8248814210ab7bd3a88e88bc06066dd25 Mon Sep 17 00:00:00 2001
From: Dan Abramov
Date: Mon, 23 Nov 2020 02:18:20 +0000
Subject: [PATCH] Failing test for Client reconciliation
---
.../src/__tests__/ReactFlightDOM-test.js | 88 +++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/packages/react-transport-dom-webpack/src/__tests__/ReactFlightDOM-test.js b/packages/react-transport-dom-webpack/src/__tests__/ReactFlightDOM-test.js
index e437c7b20bc61..4ff3ff20341c7 100644
--- a/packages/react-transport-dom-webpack/src/__tests__/ReactFlightDOM-test.js
+++ b/packages/react-transport-dom-webpack/src/__tests__/ReactFlightDOM-test.js
@@ -440,4 +440,92 @@ describe('ReactFlightDOM', () => {
'Game over
', // TODO: should not have message in prod.
);
});
+
+ // @gate experimental
+ it('should preserve state of client components on refetch', async () => {
+ const {Suspense} = React;
+
+ // Client
+
+ function Page({response}) {
+ return response.readRoot();
+ }
+
+ function Input() {
+ return ;
+ }
+
+ const InputClient = moduleReference(Input);
+
+ // Server
+
+ function App({color}) {
+ // Verify both DOM and Client children.
+ return (
+
+
+
+
+ );
+ }
+
+ const container = document.createElement('div');
+ const root = ReactDOM.unstable_createRoot(container);
+
+ const stream1 = getTestStream();
+ ReactTransportDOMServer.pipeToNodeWritable(
+ ,
+ stream1.writable,
+ webpackMap,
+ );
+ const response1 = ReactTransportDOMClient.createFromReadableStream(
+ stream1.readable,
+ );
+ await act(async () => {
+ root.render(
+ (loading)
}>
+
+ ,
+ );
+ });
+ expect(container.children.length).toBe(1);
+ expect(container.children[0].tagName).toBe('DIV');
+ expect(container.children[0].style.color).toBe('red');
+
+ // Change the DOM state for both inputs.
+ const inputA = container.children[0].children[0];
+ expect(inputA.tagName).toBe('INPUT');
+ inputA.value = 'hello';
+ const inputB = container.children[0].children[1];
+ expect(inputB.tagName).toBe('INPUT');
+ inputB.value = 'goodbye';
+
+ const stream2 = getTestStream();
+ ReactTransportDOMServer.pipeToNodeWritable(
+ ,
+ stream2.writable,
+ webpackMap,
+ );
+ const response2 = ReactTransportDOMClient.createFromReadableStream(
+ stream2.readable,
+ );
+ await act(async () => {
+ root.render(
+ (loading)}>
+
+ ,
+ );
+ });
+ expect(container.children.length).toBe(1);
+ expect(container.children[0].tagName).toBe('DIV');
+ expect(container.children[0].style.color).toBe('blue');
+
+ // Verify we didn't destroy the DOM for either input.
+ expect(inputA === container.children[0].children[0]).toBe(true);
+ expect(inputA.tagName).toBe('INPUT');
+ expect(inputA.value).toBe('hello');
+ expect(inputB === container.children[0].children[1]).toBe(true);
+ expect(inputB.tagName).toBe('INPUT');
+ expect(inputB.value).toBe('goodbye');
+ });
});