Skip to content

Commit b78918f

Browse files
committed
fix: Improve support for conditional rendering with Suspense
1 parent da63ea2 commit b78918f

4 files changed

Lines changed: 64 additions & 16 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"type": "git",
1111
"url": "https://github.com/bfanger/svelte-preprocess-react.git"
1212
},
13-
"version": "2.0.0",
13+
"version": "2.0.1",
1414
"license": "MIT",
1515
"type": "module",
1616
"scripts": {

src/lib/sveltify.svelte.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,23 @@ function single<T extends React.FC | React.ComponentClass>(
187187
(ReactWrapper as any)(anchorOrPayload, $$props);
188188

189189
if (standalone && !client) {
190+
let renderError: Error | undefined;
190191
if (renderToString && sharedRoot) {
191192
setPayload(anchorOrPayload);
192-
const html = renderToString(
193-
React.createElement(Bridge, { node: sharedRoot }),
194-
);
195-
const source = { html };
196-
applyPortals(anchorOrPayload, sharedRoot, source);
193+
try {
194+
const html = renderToString(
195+
React.createElement(Bridge, { node: sharedRoot }),
196+
);
197+
const source = { html };
198+
applyPortals(anchorOrPayload, sharedRoot, source);
199+
} catch (err) {
200+
renderError = (err as Error) ?? new Error("Unknown error");
201+
sharedRoot = undefined;
202+
}
197203
setPayload(undefined);
204+
if (renderError) {
205+
throw renderError;
206+
}
198207
}
199208
}
200209
}
@@ -236,25 +245,28 @@ function applyPortal(
236245
source.html,
237246
);
238247
} catch {
239-
// The React component, didn't render the childrenThe rendering of children can be conditional.
248+
// The React component didn't render the children, the rendering of children can be conditional.
240249
}
241250
}
242-
const portal = extract(
243-
`<react-portal-source node="${node.key}" style="display:none">`,
244-
`</react-portal-source>`,
245-
source.html,
246-
);
247-
248-
source.html = portal.outerRemoved;
249251
try {
252+
const portal = extract(
253+
`<react-portal-source node="${node.key}" style="display:none">`,
254+
`</react-portal-source>`,
255+
source.html,
256+
);
257+
258+
source.html = portal.outerRemoved;
250259
$$payload.out = inject(
251260
`<svelte-portal-target node="${node.key}" style="display:contents">`,
252261
"</svelte-portal-target>",
253262
portal.innerHtml,
254263
$$payload.out,
255264
);
256-
} catch (err: any) {
257-
console.warn(err.message);
265+
} catch (err) {
266+
if (!node.parent) {
267+
throw err;
268+
}
269+
// Nested component didn't render, could be suspense or conditional rendering.
258270
}
259271
}
260272

src/routes/broken/+page.svelte

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script lang="ts">
2+
import type * as React from "react";
3+
4+
const Broken: React.FC = () => {
5+
const condition = true;
6+
if (condition) {
7+
throw new Error("Oops, something went wrong!");
8+
}
9+
return "didn't throw?";
10+
};
11+
12+
const react = sveltify({
13+
Broken,
14+
});
15+
</script>
16+
17+
<react.Broken />

src/routes/suspense/+page.svelte

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script lang="ts">
2+
import { Suspense, lazy } from "react";
3+
4+
const react = sveltify({
5+
Suspense,
6+
Alert: lazy(
7+
() =>
8+
new Promise<any>((resolve) => {
9+
setTimeout(() => {
10+
resolve(import("../../demo/react-components/Alert"));
11+
}, 500);
12+
}),
13+
),
14+
});
15+
</script>
16+
17+
<react.Suspense fallback="Loading...">
18+
<react.Alert />
19+
</react.Suspense>

0 commit comments

Comments
 (0)