Skip to content

Commit 678c2b7

Browse files
authored
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
1 parent 13e697f commit 678c2b7

4 files changed

Lines changed: 34 additions & 22 deletions

File tree

.changeset/small-maps-cough.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'astro': patch
3+
'@astrojs/react': patch
4+
---
5+
6+
Fix: remove hydration failures on React v18 by exposing the "client" directive from Astro core.

packages/astro/src/runtime/server/hydration.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ export async function generateHydrateScript(
110110
);
111111
}
112112

113-
let hydrationSource = ``;
114-
115-
hydrationSource += renderer.clientEntrypoint
113+
const hydrationSource = renderer.clientEntrypoint
116114
? `const [{ ${
117115
componentExport.value
118116
}: Component }, { default: hydrate }] = await Promise.all([import("${await result.resolve(
119117
componentUrl
120118
)}"), import("${await result.resolve(renderer.clientEntrypoint)}")]);
121-
return (el, children) => hydrate(el)(Component, ${serializeProps(props)}, children);
119+
return (el, children) => hydrate(el)(Component, ${serializeProps(
120+
props
121+
)}, children, ${JSON.stringify({ client: hydrate })});
122122
`
123123
: `await import("${await result.resolve(componentUrl)}");
124124
return () => {};
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { createElement } from 'react';
2-
import { hydrate } from 'react-dom';
2+
import { render, hydrate } from 'react-dom';
33
import StaticHtml from './static-html.js';
44

5-
export default (element) => (Component, props, children) =>
6-
hydrate(
7-
createElement(
5+
export default (element) => (Component, props, children, { client }) =>
6+
{
7+
const componentEl = createElement(
88
Component,
9-
{ ...props, suppressHydrationWarning: true },
9+
props,
1010
children != null
11-
? createElement(StaticHtml, { value: children, suppressHydrationWarning: true })
11+
? createElement(StaticHtml, { value: children })
1212
: children
13-
),
14-
element
15-
);
13+
);
14+
if (client === 'only') {
15+
return render(componentEl, element);
16+
}
17+
return hydrate(componentEl, element);
18+
};
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { createElement } from 'react';
2-
import { hydrateRoot } from 'react-dom/client';
2+
import { createRoot, hydrateRoot } from 'react-dom/client';
33
import StaticHtml from './static-html.js';
44

5-
export default (element) => (Component, props, children) =>
6-
hydrateRoot(
7-
element,
8-
createElement(
5+
export default (element) => (Component, props, children, { client }) =>
6+
{
7+
const componentEl = createElement(
98
Component,
10-
{ ...props, suppressHydrationWarning: true },
9+
props,
1110
children != null
12-
? createElement(StaticHtml, { value: children, suppressHydrationWarning: true })
11+
? createElement(StaticHtml, { value: children })
1312
: children
14-
)
15-
);
13+
);
14+
if (client === 'only') {
15+
return createRoot(element).render(componentEl);
16+
}
17+
return hydrateRoot(element, componentEl);
18+
};

0 commit comments

Comments
 (0)