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
This commit is contained in:
parent
13e697fb80
commit
678c2b7523
4 changed files with 34 additions and 22 deletions
6
.changeset/small-maps-cough.md
Normal file
6
.changeset/small-maps-cough.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
'@astrojs/react': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix: remove hydration failures on React v18 by exposing the "client" directive from Astro core.
|
|
@ -110,15 +110,15 @@ export async function generateHydrateScript(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hydrationSource = ``;
|
const hydrationSource = renderer.clientEntrypoint
|
||||||
|
|
||||||
hydrationSource += renderer.clientEntrypoint
|
|
||||||
? `const [{ ${
|
? `const [{ ${
|
||||||
componentExport.value
|
componentExport.value
|
||||||
}: Component }, { default: hydrate }] = await Promise.all([import("${await result.resolve(
|
}: Component }, { default: hydrate }] = await Promise.all([import("${await result.resolve(
|
||||||
componentUrl
|
componentUrl
|
||||||
)}"), import("${await result.resolve(renderer.clientEntrypoint)}")]);
|
)}"), 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)}");
|
: `await import("${await result.resolve(componentUrl)}");
|
||||||
return () => {};
|
return () => {};
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
import { hydrate } from 'react-dom';
|
import { render, hydrate } from 'react-dom';
|
||||||
import StaticHtml from './static-html.js';
|
import StaticHtml from './static-html.js';
|
||||||
|
|
||||||
export default (element) => (Component, props, children) =>
|
export default (element) => (Component, props, children, { client }) =>
|
||||||
hydrate(
|
{
|
||||||
createElement(
|
const componentEl = createElement(
|
||||||
Component,
|
Component,
|
||||||
{ ...props, suppressHydrationWarning: true },
|
props,
|
||||||
children != null
|
children != null
|
||||||
? createElement(StaticHtml, { value: children, suppressHydrationWarning: true })
|
? createElement(StaticHtml, { value: children })
|
||||||
: children
|
: children
|
||||||
),
|
);
|
||||||
element
|
if (client === 'only') {
|
||||||
);
|
return render(componentEl, element);
|
||||||
|
}
|
||||||
|
return hydrate(componentEl, element);
|
||||||
|
};
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
import { hydrateRoot } from 'react-dom/client';
|
import { createRoot, hydrateRoot } from 'react-dom/client';
|
||||||
import StaticHtml from './static-html.js';
|
import StaticHtml from './static-html.js';
|
||||||
|
|
||||||
export default (element) => (Component, props, children) =>
|
export default (element) => (Component, props, children, { client }) =>
|
||||||
hydrateRoot(
|
{
|
||||||
element,
|
const componentEl = createElement(
|
||||||
createElement(
|
|
||||||
Component,
|
Component,
|
||||||
{ ...props, suppressHydrationWarning: true },
|
props,
|
||||||
children != null
|
children != null
|
||||||
? createElement(StaticHtml, { value: children, suppressHydrationWarning: true })
|
? createElement(StaticHtml, { value: children })
|
||||||
: children
|
: children
|
||||||
)
|
);
|
||||||
);
|
if (client === 'only') {
|
||||||
|
return createRoot(element).render(componentEl);
|
||||||
|
}
|
||||||
|
return hydrateRoot(element, componentEl);
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue