summaryrefslogtreecommitdiff
path: root/packages/integrations/react/client.js
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2024-03-08 05:54:16 -0500
committerGravatar GitHub <noreply@github.com> 2024-03-08 10:54:16 +0000
commit9cd84bd19b92fb43ae48809f575ee12ebd43ea8f (patch)
tree65a1a2f5343566cb89b133ef86fad3f3bd50c9d5 /packages/integrations/react/client.js
parent3307cb34f17159dfd3f03144697040fcaa10e903 (diff)
downloadastro-9cd84bd19b92fb43ae48809f575ee12ebd43ea8f.tar.gz
astro-9cd84bd19b92fb43ae48809f575ee12ebd43ea8f.tar.zst
astro-9cd84bd19b92fb43ae48809f575ee12ebd43ea8f.zip
Allow islands to be re-rendered with new props on page transition (#10136)
* Allow islands to be re-rendered with new props on page transition * Adjust the expected styles * Restore test expectation * Add changeset and final change * linting * Implement transition:persist-props behavior * Fix lockfile * Fix expectations * App is hyrid * Update .changeset/lovely-nails-cough.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update .changeset/lovely-nails-cough.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update .changeset/lovely-nails-cough.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --------- Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Diffstat (limited to 'packages/integrations/react/client.js')
-rw-r--r--packages/integrations/react/client.js25
1 files changed, 21 insertions, 4 deletions
diff --git a/packages/integrations/react/client.js b/packages/integrations/react/client.js
index 90e4ceb83..cfe46a919 100644
--- a/packages/integrations/react/client.js
+++ b/packages/integrations/react/client.js
@@ -53,6 +53,17 @@ function getChildren(childString, experimentalReactChildren) {
}
}
+// Keep a map of roots so we can reuse them on re-renders
+let rootMap = new WeakMap();
+const getOrCreateRoot = (element, creator) => {
+ let root = rootMap.get(element);
+ if(!root) {
+ root = creator();
+ rootMap.set(element, root);
+ }
+ return root;
+};
+
export default (element) =>
(Component, props, { default: children, ...slotted }, { client }) => {
if (!element.hasAttribute('ssr')) return;
@@ -75,14 +86,20 @@ export default (element) =>
}
if (client === 'only') {
return startTransition(() => {
- const root = createRoot(element);
+ const root = getOrCreateRoot(element, () => {
+ const r = createRoot(element);
+ element.addEventListener('astro:unmount', () => r.unmount(), { once: true });
+ return r;
+ });
root.render(componentEl);
- element.addEventListener('astro:unmount', () => root.unmount(), { once: true });
});
}
startTransition(() => {
- const root = hydrateRoot(element, componentEl, renderOptions);
+ const root = getOrCreateRoot(element, () => {
+ const r = hydrateRoot(element, componentEl, renderOptions);
+ element.addEventListener('astro:unmount', () => r.unmount(), { once: true });
+ return r;
+ });
root.render(componentEl);
- element.addEventListener('astro:unmount', () => root.unmount(), { once: true });
});
};