diff options
Diffstat (limited to 'packages/integrations/react/client.js')
-rw-r--r-- | packages/integrations/react/client.js | 25 |
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 }); }); }; |