陷阱

renderToString 不支持流式传输或等待数据。请参考替代方案

renderToString 将 React 树渲染为一个 HTML 字符串。

const html = renderToString(reactNode, options?)

Reference

renderToString(reactNode, options?)

在服务器,调用 renderToString 将你的应用渲染为 HTML。

import { renderToString } from 'react-dom/server';

const html = renderToString(<App />);

在客户端,调用 hydrateRoot 来使服务器生成的 HTML 具有交互性。

请参考下面的更多示例

参数

  • reactNode:你要渲染为 HTML 的 React 节点。例如,一个 JSX 节点,就像 <App />

  • optional options: An object for server render.

    • optional identifierPrefix: A string prefix React uses for IDs generated by useId. Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to hydrateRoot.

Returns

一个 HTML 字符串。

注意事项

  • renderToString 对 Suspense 的支持有限。如果一个组件挂起(suspend),renderToString 会立即将其后备方案作为 HTML 发送。

  • renderToString 可以在浏览器中工作,但 不推荐 在客户端代码中使用它。


用法

将 React 树渲染为 HTML 字符串

调用 renderToString 将你的应用渲染为 HTML 字符串,你可以将其与服务器响应一起发送:

import { renderToString } from 'react-dom/server';

// 路由处理程序的语法取决于你使用的后端框架
app.use('/', (request, response) => {
const html = renderToString(<App />);
response.send(html);
});

这将生成你的 React 组件的初始非交互式 HTML 输出。在客户端上,你需要调用 hydrateRoot 来将服务器生成的 HTML 进行激活处理,使其具有交互功能。

陷阱

renderToString 不支持流式传输或等待数据。请参考替代方案


替代方案

renderToString 迁移到服务器上的流式传输方法

renderToString 立即返回一个字符串,因此不支持加载时流式传输内容。

如果可能的话,我们建议使用这些功能完整的替代方法:

如果你的服务器环境不支持流式传输,你仍然可以继续使用 renderToString


Migrating from renderToString to a static prerender on the server

renderToString returns a string immediately, so it does not support waiting for data to load for static HTML generation.

We recommend using these fully-featured alternatives:

You can continue using renderToString if your static site generation environment does not support streams.


从客户端代码中移除 renderToString

有时,renderToString 用于在客户端将某个组件转换为 HTML。

// 🚩 不必要:在客户端使用 renderToString
import { renderToString } from 'react-dom/server';

const html = renderToString(<MyIcon />);
console.log(html); // 例如,"<svg>...</svg>"

在客户端导入 react-dom/server 会不必要地增加 bundle 大小,所以应该避免这样做。如果你需要在浏览器中将某个组件渲染为 HTML,请使用 createRoot 并从 DOM 中读取 HTML。

import { createRoot } from 'react-dom/client';
import { flushSync } from 'react-dom';

const div = document.createElement('div');
const root = createRoot(div);
flushSync(() => {
root.render(<MyIcon />);
});
console.log(div.innerHTML); // 例如,"<svg>...</svg>"

flushSync 调用是必要的,以便在读取 innerHTML 属性之前更新 DOM。


故障排除

当组件暂停时,HTML 中始终包含一个后备方案

renderToString 不完全支持 Suspense。

如果某个组件 suspend(例如,因为它使用 lazy 定义或获取数据),renderToString 不会等待其内容解析完成。相反,renderToString 将找到最近的 <Suspense> 边界,并在 HTML 中渲染其 fallback 属性。直到客户端代码加载后,内容才会显示出来。

要解决这个问题,请使用 推荐的流式解决方案之一。 对于服务器端渲染,它们可以在服务器上以块的形式流式传输内容,以便用户在客户端代码加载之前逐步看到页面被填充。对于静态站点,他们可以等待所有内容解析后再生成静态 HTML。