diff --git a/src/content/reference/react-dom/server/resume.md b/src/content/reference/react-dom/server/resume.md index ad61f6da56..1c8be96097 100644 --- a/src/content/reference/react-dom/server/resume.md +++ b/src/content/reference/react-dom/server/resume.md @@ -4,7 +4,7 @@ title: resume -`resume` streams a pre-rendered React tree to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) +`resume` 将预渲染的 React 树流式传输到 [Web 可读流](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)。 ```js const stream = await resume(reactNode, postponedState, options?) @@ -16,17 +16,17 @@ const stream = await resume(reactNode, postponedState, options?) -This API depends on [Web Streams.](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) For Node.js, use [`resumeToNodeStream`](/reference/react-dom/server/renderToPipeableStream) instead. +此 API 依赖于 [Web 流](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)。对于 Node.js,请改用 [`resumeToNodeStream`](/reference/react-dom/server/renderToPipeableStream)。 --- -## Reference {/*reference*/} +## 参考 {/*reference*/} ### `resume(node, postponedState, options?)` {/*resume*/} -Call `resume` to resume rendering a pre-rendered React tree as HTML into a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) +调用 `resume`,将预渲染的 React 树继续渲染为 HTML,并写入 [Web 可读流](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)。 ```js import { resume } from 'react-dom/server'; @@ -39,39 +39,39 @@ async function handler(request, writable) { } ``` -[See more examples below.](#usage) +[请参阅下面的更多示例](#usage)。 -#### Parameters {/*parameters*/} +#### 参数 {/*parameters*/} -* `reactNode`: The React node you called `prerender` with. For example, a JSX element like ``. It is expected to represent the entire document, so the `App` component should render the `` tag. -* `postponedState`: The opaque `postpone` object returned from a [prerender API](/reference/react-dom/static/index), loaded from wherever you stored it (e.g. redis, a file, or S3). -* **optional** `options`: An object with streaming options. - * **optional** `nonce`: A [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) string to allow scripts for [`script-src` Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src). - * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort server rendering](#aborting-server-rendering) and render the rest on the client. - * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-outside-the-shell) or [not.](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](/reference/react-dom/server/renderToReadableStream#logging-crashes-on-the-server) make sure that you still call `console.error`. +* `reactNode`:调用 `prerender` 时传入的 React 节点。例如,像 `` 这样的 JSX 元素。它应表示整个文档,因此 `App` 组件应渲染 `` 标签。 +* `postponedState`:从 [prerender API](/reference/react-dom/static/index) 返回的不透明 `postpone` 对象,从你存储它的位置加载(例如 Redis、文件或 S3)。 +* **可选** `options`:包含流式传输选项的对象。 + * **可选** `nonce`:一个 [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) 字符串,用于允许 [`script-src` 内容安全策略](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src) 中的脚本。 + * **可选** `signal`:一个 [中止信号](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal),允许你 [中止服务端渲染](#aborting-server-rendering),并在客户端渲染剩余内容。 + * **可选** `onError`:每当发生服务端错误时触发的回调函数,无论错误是 [可恢复](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-outside-the-shell) 还是 [不可恢复](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-inside-the-shell)。默认情况下,它只调用 `console.error`。如果你重写它来 [记录崩溃报告](/reference/react-dom/server/renderToReadableStream#logging-crashes-on-the-server),请确保仍然调用 `console.error`。 -#### Returns {/*returns*/} +#### 返回值 {/*returns*/} -`resume` returns a Promise: +`resume` 返回一个 Promise: -- If `resume` successfully produced a [shell](/reference/react-dom/server/renderToReadableStream#specifying-what-goes-into-the-shell), that Promise will resolve to a [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) that can be piped to a [Writable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream). -- If an error happens in the shell, the Promise will reject with that error. +- 如果 `resume` 成功生成了 [shell](/reference/react-dom/server/renderToReadableStream#specifying-what-goes-into-the-shell),该 Promise 将解析为一个 [Web 可读流](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream),可以将其通过管道传输到 [Web 可写流](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream)。 +- 如果 shell 中发生错误,Promise 将因该错误而被拒绝。 -The returned stream has an additional property: +返回的流还有一个额外属性: -* `allReady`: A Promise that resolves when all rendering is complete. You can `await stream.allReady` before returning a response [for crawlers and static generation.](/reference/react-dom/server/renderToReadableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation) If you do that, you won't get any progressive loading. The stream will contain the final HTML. +* `allReady`:一个在所有渲染完成后解析的 Promise。你可以在返回响应之前 `await stream.allReady`,以供 [爬虫和静态生成](/reference/react-dom/server/renderToReadableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation) 使用。这样做不会有任何渐进式加载,流中将包含最终的 HTML。 -#### Caveats {/*caveats*/} +#### 注意事项 {/*caveats*/} -- `resume` does not accept options for `bootstrapScripts`, `bootstrapScriptContent`, or `bootstrapModules`. Instead, you need to pass these options to the `prerender` call that generates the `postponedState`. You can also inject bootstrap content into the writable stream manually. -- `resume` does not accept `identifierPrefix` since the prefix needs to be the same in both `prerender` and `resume`. -- Since `nonce` cannot be provided to prerender, you should only provide `nonce` to `resume` if you're not providing scripts to prerender. -- `resume` re-renders from the root until it finds a component that was not fully pre-rendered. Only fully prerendered Components (the Component and its children finished prerendering) are skipped entirely. +- `resume` 不接受 `bootstrapScripts`、`bootstrapScriptContent` 或 `bootstrapModules` 选项。相反,你需要将这些选项传递给生成 `postponedState` 的 `prerender` 调用。你也可以手动将引导内容注入可写流。 +- `resume` 不接受 `identifierPrefix`,因为该前缀在 `prerender` 和 `resume` 中必须保持一致。 +- 由于不能向 `prerender` 提供 `nonce`,只有在没有向 `prerender` 提供脚本时,才应向 `resume` 提供 `nonce`。 +- `resume` 会从根节点重新渲染,直到找到一个未完全预渲染的组件。只有完全预渲染的组件(组件及其子组件都已完成预渲染)才会被完全跳过。 -## Usage {/*usage*/} +## 用法 {/*usage*/} -### Resuming a prerender {/*resuming-a-prerender*/} +### 恢复预渲染 {/*resuming-a-prerender*/} @@ -80,11 +80,11 @@ The returned stream has an additional property: ```html public/index.html - + - Document + 文档 @@ -105,7 +105,7 @@ import { resume } from "react-dom/server"; import { hydrateRoot } from "react-dom/client"; function Header() { - return
Me and my descendants can be prerendered
; + return
我和我的后代都可以被预渲染
; } const { promise: cookies, resolve: resolveCookies } = Promise.withResolvers(); @@ -115,22 +115,22 @@ function Main() { const user = getUser(sessionID); useEffect(() => { - console.log("reached interactivity!"); + console.log("已达到交互状态!"); }, []); return (
- Hello, {user.name}! -
); } function Shell({ children }) { - // In a real app, this is where you would put your html and body. - // We're just using tags here we can include in an existing body for demonstration purposes + // 在真实应用中,你应在此处放置 html 和 body。 + // 这里只是为了演示,使用可以包含在现有 body 中的标签。 return ( {children} @@ -141,10 +141,10 @@ function Shell({ children }) { function App() { return ( - +
- +
@@ -152,7 +152,7 @@ function App() { } async function main(frame) { - // Layer 1 + // 第 1 层 const controller = new AbortController(); const prerenderedApp = prerender(, { signal: controller.signal, @@ -163,8 +163,8 @@ async function main(frame) { } }, }); - // We're immediately aborting in a macrotask. - // Any data fetching that's not available synchronously, or in a microtask, will not have finished. + // 我们会立即在宏任务中止该过程。 + // 任何无法同步获取或无法在微任务中获取的数据,都不会完成加载。 setTimeout(() => { controller.abort(new Postponed()); }); @@ -172,22 +172,21 @@ async function main(frame) { const { prelude, postponed } = await prerenderedApp; await flushReadableStreamToFrame(prelude, frame); - // Layer 2 - // Just waiting here for demonstration purposes. - // In a real app, the prelude and postponed state would've been serialized in Layer 1 and Layer would deserialize them. - // The prelude content could be flushed immediated as plain HTML while - // React is continuing to render from where the prerender left off. + // 第 2 层 + // 这里只是为了演示而等待。 + // 在真实应用中,prelude 和 postponed 状态会在第 1 层序列化,并在这一层反序列化。 + // 在 React 从预渲染中断处继续渲染的同时,prelude 内容可以立即作为普通 HTML 刷新。 await sleep(2000); - // You would get the cookies from the incoming HTTP request + // 你会从传入的 HTTP 请求中获取 cookie resolveCookies({ sessionID: "abc" }); const stream = await resume(, postponed); await flushReadableStreamToFrame(stream, frame); - // Layer 3 - // Just waiting here for demonstration purposes. + // 第 3 层 + // 这里只是为了演示而等待。 await sleep(2000); hydrateRoot(frame.contentWindow.document, ); @@ -207,12 +206,12 @@ export async function flushReadableStreamToFrame(readable, frame) { } } -// This doesn't need to be an error. -// You can use any other means to check if an error during prerender was -// from an intentional abort or a real error. +// 这不一定要是一个错误。 +// 你可以使用其他任何方式来判断预渲染期间的错误 +// 是由有意中止导致的,还是实际错误。 export class Postponed extends Error {} -// We're just hardcoding a session here. +// 这里只是硬编码一个会话。 export function getUser(sessionID) { return { name: "Alice", @@ -230,7 +229,7 @@ export function sleep(timeoutMS) { -### Further reading {/*further-reading*/} +### 延伸阅读 {/*further-reading*/} -Resuming behaves like `renderToReadableStream`. For more examples, check out the [usage section of `renderToReadableStream`](/reference/react-dom/server/renderToReadableStream#usage). -The [usage section of `prerender`](/reference/react-dom/static/prerender#usage) includes examples of how to use `prerender` specifically. \ No newline at end of file +恢复过程的行为类似于 `renderToReadableStream`。有关更多示例,请参阅 [`renderToReadableStream` 的用法部分](/reference/react-dom/server/renderToReadableStream#usage)。 +[`prerender` 的用法部分](/reference/react-dom/static/prerender#usage) 包含专门介绍如何使用 `prerender` 的示例。