Skip to content

Commit c819f51

Browse files
authored
Ensure use id works (#411)
* Ensure useId works properly * Tweak changeset
1 parent 8e8e8ac commit c819f51

File tree

6 files changed

+51
-14
lines changed

6 files changed

+51
-14
lines changed

.changeset/friendly-numbers-hang.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
'preact-render-to-string': patch
33
---
44

5-
Fix issue where subtree re-render for Suspense boundaries caused a circular reference in the VNode's parent
5+
Ensure that the `_parent` is kept around across multiple suspensions and avoid circular references.
6+
In doing so our `useId` hook should always output unique ids during renderingToString.

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,6 @@ function _renderToString(
443443
return EMPTY_STR;
444444
} finally {
445445
if (afterDiff) afterDiff(vnode);
446-
vnode[PARENT] = null;
447446

448447
if (ummountHook) ummountHook(vnode);
449448
}
@@ -473,7 +472,6 @@ function _renderToString(
473472

474473
if (afterDiff) afterDiff(vnode);
475474
// when we are dealing with suspense we can't do this...
476-
vnode[PARENT] = null;
477475

478476
if (options.unmount) options.unmount(vnode);
479477

@@ -688,9 +686,6 @@ function _renderToString(
688686

689687
if (afterDiff) afterDiff(vnode);
690688

691-
// TODO: this was commented before
692-
vnode[PARENT] = null;
693-
694689
if (ummountHook) ummountHook(vnode);
695690

696691
// Emit self-closing tag for empty void elements:

test/compat/render-chunked.test.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,48 @@ describe('renderToChunks', () => {
145145
'<div><p>id: P0-0</p><!--preact-island:24-->loading...<!--/preact-island:24--></div>',
146146
'<div hidden>',
147147
createInitScript(1),
148-
createSubtree('24', '<p>id: P0-0</p>'),
148+
createSubtree('24', '<p>id: P0-1</p>'),
149+
'</div>'
150+
]);
151+
});
152+
153+
it('should support using multiple useId hooks inside multiple suspense boundaries', async () => {
154+
const { Suspender, suspended } = createSuspender();
155+
const { Suspender: Suspender2, suspended: suspended2 } = createSuspender();
156+
157+
function ComponentWithId() {
158+
const id = useId();
159+
return <p>id: {id}</p>;
160+
}
161+
162+
const result = [];
163+
const promise = renderToChunks(
164+
<div>
165+
<ComponentWithId />
166+
<Suspense fallback="loading...">
167+
<Suspender>
168+
<ComponentWithId />
169+
</Suspender>
170+
</Suspense>
171+
<Suspense fallback="loading...">
172+
<Suspender2>
173+
<ComponentWithId />
174+
</Suspender2>
175+
</Suspense>
176+
</div>,
177+
{ onWrite: (s) => result.push(s) }
178+
);
179+
180+
suspended.resolve();
181+
suspended2.resolve();
182+
await promise;
183+
184+
expect(result).to.deep.equal([
185+
'<div><p>id: P0-0</p><!--preact-island:33-->loading...<!--/preact-island:33--><!--preact-island:36-->loading...<!--/preact-island:36--></div>',
186+
'<div hidden>',
187+
createInitScript(1),
188+
createSubtree('33', '<p>id: P0-1</p>'),
189+
createSubtree('36', '<p>id: P0-2</p>'),
149190
'</div>'
150191
]);
151192
});

test/compat/stream-node.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ describe('renderToPipeableStream', () => {
6666
const result = await sink.promise;
6767

6868
expect(result).to.deep.equal([
69-
'<div><!--preact-island:33-->loading...<!--/preact-island:33--></div>',
69+
'<div><!--preact-island:47-->loading...<!--/preact-island:47--></div>',
7070
'<div hidden>',
7171
createInitScript(),
72-
createSubtree('33', '<p>it works</p>'),
72+
createSubtree('47', '<p>it works</p>'),
7373
'</div>'
7474
]);
7575
});

test/compat/stream.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ describe('renderToReadableStream', () => {
8282
const result = await sink.promise;
8383

8484
expect(result).to.deep.equal([
85-
'<div><!--preact-island:40-->loading...<!--/preact-island:40--></div>',
85+
'<div><!--preact-island:54-->loading...<!--/preact-island:54--></div>',
8686
'<div hidden>',
8787
createInitScript(),
88-
createSubtree('40', '<p>it works</p>'),
88+
createSubtree('54', '<p>it works</p>'),
8989
'</div>'
9090
]);
9191
});

0 commit comments

Comments
 (0)