diff options
author | 2023-05-04 15:23:00 +0100 | |
---|---|---|
committer | 2023-05-04 15:23:00 +0100 | |
commit | ca329bbcae7a6075af4f428f6f64466e9d152c8f (patch) | |
tree | 0139a99c0cc60b22758e75ebb519893a5447ebb2 /packages/integrations/react/server.js | |
parent | dfb9e4270a7c05c292a549777408278fcbe162ab (diff) | |
download | astro-ca329bbcae7a6075af4f428f6f64466e9d152c8f.tar.gz astro-ca329bbcae7a6075af4f428f6f64466e9d152c8f.tar.zst astro-ca329bbcae7a6075af4f428f6f64466e9d152c8f.zip |
Generate unique ids within each React island (#6976)
Diffstat (limited to 'packages/integrations/react/server.js')
-rw-r--r-- | packages/integrations/react/server.js | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/packages/integrations/react/server.js b/packages/integrations/react/server.js index 01a135a9b..0d85984f9 100644 --- a/packages/integrations/react/server.js +++ b/packages/integrations/react/server.js @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom/server'; import StaticHtml from './static-html.js'; +import { incrementId } from './context.js'; const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); const reactTypeof = Symbol.for('react.element'); @@ -58,6 +59,12 @@ async function getNodeWritable() { } async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) { + let prefix; + if (this && this.result) { + prefix = incrementId(this.result) + } + const attrs = { prefix }; + delete props['class']; const slots = {}; for (const [key, value] of Object.entries(slotted)) { @@ -74,29 +81,33 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl newProps.children = React.createElement(StaticHtml, { value: newChildren }); } const vnode = React.createElement(Component, newProps); + const renderOptions = { + identifierPrefix: prefix + } let html; if (metadata && metadata.hydrate) { if ('renderToReadableStream' in ReactDOM) { - html = await renderToReadableStreamAsync(vnode); + html = await renderToReadableStreamAsync(vnode, renderOptions); } else { - html = await renderToPipeableStreamAsync(vnode); + html = await renderToPipeableStreamAsync(vnode, renderOptions); } } else { if ('renderToReadableStream' in ReactDOM) { - html = await renderToReadableStreamAsync(vnode); + html = await renderToReadableStreamAsync(vnode, renderOptions); } else { - html = await renderToStaticNodeStreamAsync(vnode); + html = await renderToStaticNodeStreamAsync(vnode, renderOptions); } } - return { html }; + return { html, attrs }; } -async function renderToPipeableStreamAsync(vnode) { +async function renderToPipeableStreamAsync(vnode, options) { const Writable = await getNodeWritable(); let html = ''; return new Promise((resolve, reject) => { let error = undefined; let stream = ReactDOM.renderToPipeableStream(vnode, { + ...options, onError(err) { error = err; reject(error); @@ -118,11 +129,11 @@ async function renderToPipeableStreamAsync(vnode) { }); } -async function renderToStaticNodeStreamAsync(vnode) { +async function renderToStaticNodeStreamAsync(vnode, options) { const Writable = await getNodeWritable(); let html = ''; return new Promise((resolve, reject) => { - let stream = ReactDOM.renderToStaticNodeStream(vnode); + let stream = ReactDOM.renderToStaticNodeStream(vnode, options); stream.on('error', (err) => { reject(err); }); @@ -164,8 +175,8 @@ async function readResult(stream) { } } -async function renderToReadableStreamAsync(vnode) { - return await readResult(await ReactDOM.renderToReadableStream(vnode)); +async function renderToReadableStreamAsync(vnode, options) { + return await readResult(await ReactDOM.renderToReadableStream(vnode, options)); } export default { |