summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ben Holmes <hey@bholmes.dev> 2022-05-12 10:05:55 -0600
committerGravatar GitHub <noreply@github.com> 2022-05-12 10:05:55 -0600
commit678c2b7523c7f10cfdf2eb5a73aa2bbb7e5cbc07 (patch)
tree8486dc5e86527d21a0ef686a1cc47658ec51aeb3
parent13e697fb8042930aa76a4b81f54f014c901039db (diff)
downloadastro-678c2b7523c7f10cfdf2eb5a73aa2bbb7e5cbc07.tar.gz
astro-678c2b7523c7f10cfdf2eb5a73aa2bbb7e5cbc07.tar.zst
astro-678c2b7523c7f10cfdf2eb5a73aa2bbb7e5cbc07.zip
Fix: React - Use "createRoot" instead of "hydrateRoot" for `client:only` (#3337)
* feat: pass "client" directive to clientEntrypoints * refactor: remove hydration warning suppression react 17 * feat: remove hydration warning suppression react 18 * chore: changeset * fix: change metadata to options bag
Diffstat (limited to '')
-rw-r--r--.changeset/small-maps-cough.md6
-rw-r--r--packages/astro/src/runtime/server/hydration.ts8
-rw-r--r--packages/integrations/react/client-v17.js21
-rw-r--r--packages/integrations/react/client.js21
4 files changed, 34 insertions, 22 deletions
diff --git a/.changeset/small-maps-cough.md b/.changeset/small-maps-cough.md
new file mode 100644
index 000000000..aadc443d2
--- /dev/null
+++ b/.changeset/small-maps-cough.md
@@ -0,0 +1,6 @@
+---
+'astro': patch
+'@astrojs/react': patch
+---
+
+Fix: remove hydration failures on React v18 by exposing the "client" directive from Astro core.
diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts
index e7267fe16..4d8ab48f0 100644
--- a/packages/astro/src/runtime/server/hydration.ts
+++ b/packages/astro/src/runtime/server/hydration.ts
@@ -110,15 +110,15 @@ export async function generateHydrateScript(
);
}
- let hydrationSource = ``;
-
- hydrationSource += renderer.clientEntrypoint
+ const hydrationSource = renderer.clientEntrypoint
? `const [{ ${
componentExport.value
}: Component }, { default: hydrate }] = await Promise.all([import("${await result.resolve(
componentUrl
)}"), import("${await result.resolve(renderer.clientEntrypoint)}")]);
- return (el, children) => hydrate(el)(Component, ${serializeProps(props)}, children);
+ return (el, children) => hydrate(el)(Component, ${serializeProps(
+ props
+ )}, children, ${JSON.stringify({ client: hydrate })});
`
: `await import("${await result.resolve(componentUrl)}");
return () => {};
diff --git a/packages/integrations/react/client-v17.js b/packages/integrations/react/client-v17.js
index 64284a0b0..32ba87558 100644
--- a/packages/integrations/react/client-v17.js
+++ b/packages/integrations/react/client-v17.js
@@ -1,15 +1,18 @@
import { createElement } from 'react';
-import { hydrate } from 'react-dom';
+import { render, hydrate } from 'react-dom';
import StaticHtml from './static-html.js';
-export default (element) => (Component, props, children) =>
- hydrate(
- createElement(
+export default (element) => (Component, props, children, { client }) =>
+ {
+ const componentEl = createElement(
Component,
- { ...props, suppressHydrationWarning: true },
+ props,
children != null
- ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true })
+ ? createElement(StaticHtml, { value: children })
: children
- ),
- element
- );
+ );
+ if (client === 'only') {
+ return render(componentEl, element);
+ }
+ return hydrate(componentEl, element);
+ };
diff --git a/packages/integrations/react/client.js b/packages/integrations/react/client.js
index 7eba8984c..0579f4a08 100644
--- a/packages/integrations/react/client.js
+++ b/packages/integrations/react/client.js
@@ -1,15 +1,18 @@
import { createElement } from 'react';
-import { hydrateRoot } from 'react-dom/client';
+import { createRoot, hydrateRoot } from 'react-dom/client';
import StaticHtml from './static-html.js';
-export default (element) => (Component, props, children) =>
- hydrateRoot(
- element,
- createElement(
+export default (element) => (Component, props, children, { client }) =>
+ {
+ const componentEl = createElement(
Component,
- { ...props, suppressHydrationWarning: true },
+ props,
children != null
- ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true })
+ ? createElement(StaticHtml, { value: children })
: children
- )
- );
+ );
+ if (client === 'only') {
+ return createRoot(element).render(componentEl);
+ }
+ return hydrateRoot(element, componentEl);
+ };