Skip to content

Commit 70af09a

Browse files
committed
fix: preserve hydration state when resuming suspended hydration
1 parent 7670785 commit 70af09a

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

compat/test/browser/suspense-hydration.test.jsx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import React, {
55
Fragment,
66
Suspense,
77
memo,
8-
useState
8+
useState,
9+
useSyncExternalStore
910
} from 'preact/compat';
1011
import { logCall, getLog, clearLog } from '../../../test/_util/logCall';
1112
import {
@@ -98,6 +99,46 @@ describe('suspense hydration', () => {
9899
});
99100
});
100101

102+
it('should use the server snapshot when suspended hydration resumes', async () => {
103+
scratch.innerHTML = '<div>server</div>';
104+
clearLog();
105+
106+
const snapshots = [];
107+
const [Lazy, resolve] = createLazy();
108+
109+
function StoreValue() {
110+
const value = useSyncExternalStore(
111+
() => () => {},
112+
() => {
113+
snapshots.push('client');
114+
return 'client';
115+
},
116+
() => {
117+
snapshots.push('server');
118+
return 'server';
119+
}
120+
);
121+
return <div>{value}</div>;
122+
}
123+
124+
hydrate(
125+
<Suspense>
126+
<Lazy />
127+
</Suspense>,
128+
scratch
129+
);
130+
rerender();
131+
expect(snapshots).to.deep.equal([]);
132+
133+
await resolve(() => <StoreValue />);
134+
rerender();
135+
136+
const [first, ...rest] = snapshots;
137+
expect(first).to.equal('server');
138+
expect(rest.every(snap => snap === 'client')).to.equal(true);
139+
expect(scratch.innerHTML).to.equal('<div>client</div>');
140+
});
141+
101142
it('Should not crash when oldVNode._children is null during shouldComponentUpdate optimization', () => {
102143
const originalHtml = '<div>Hello</div>';
103144
scratch.innerHTML = originalHtml;

src/diff/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export function diff(
8383
(isHydrating = oldVNode._flags & MODE_HYDRATE) &&
8484
oldVNode._component._excess
8585
) {
86+
newVNode._flags |= MODE_HYDRATE;
8687
let excess = oldVNode._component._excess;
8788
excessDomChildren = [];
8889
if (excess.nodeType == 8) {

0 commit comments

Comments
 (0)