diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index fc7a7b5a6c..7c155a36bf 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -973,6 +973,23 @@ Effect Event 是 Effect 代码的非响应式“片段”。他们应该在使 +```json package.json hidden +{ + "dependencies": { + "react": "experimental", + "react-dom": "experimental", + "react-scripts": "latest" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + } +} +``` + + ```js import { useState, useEffect } from 'react'; @@ -1026,6 +1043,22 @@ button { margin: 10px; } +```json package.json hidden +{ + "dependencies": { + "react": "experimental", + "react-dom": "experimental", + "react-scripts": "latest" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + } +} +``` + ```js import { useState, useEffect } from 'react'; diff --git a/src/content/reference/react-dom/static/prerender.md b/src/content/reference/react-dom/static/prerender.md index e091a8d555..2a11634e62 100644 --- a/src/content/reference/react-dom/static/prerender.md +++ b/src/content/reference/react-dom/static/prerender.md @@ -57,7 +57,7 @@ async function handler(request) { * **可选** `namespaceURI`:流的根 [命名空间 URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) 的字符串。默认为常规 HTML。对于 SVG,请传递 `'http://www.w3.org/2000/svg'`;对于 MathML,请传递 `'http://www.w3.org/1998/Math/MathML'`。 * **可选** `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`。你还可以使用它在 shell 被生成之前 [调整状态码](/reference/react-dom/server/renderToReadableStream#setting-the-status-code)。 * **可选** `progressiveChunkSize`:每个块的字节数。[阅读更多关于默认启发式的信息。](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) - * **可选** `signal`:一个 [中止信号](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal),允许你 [中止服务器渲染](/reference/react-dom/server/renderToReadableStream#aborting-server-rendering) 并在客户端渲染剩余内容。 + * **可选** `signal`:一个 [中止信号](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal),允许你 [中止预渲染](#aborting-prerendering) 并在客户端渲染剩余内容。 #### 返回值 {/*returns*/} @@ -66,7 +66,9 @@ async function handler(request) { - `prelude`:一个 [Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) 的 HTML。你可以使用此流以块的形式发送响应,或者将整个流读取为字符串。 - 如果渲染失败,Promise 将被拒绝。[使用此方法输出一个回退 shell。](/reference/react-dom/server/renderToReadableStream#recovering-from-errors-inside-the-shell) +#### Caveats {/*caveats*/} +`nonce` is not an available option when prerendering. Nonces must be unique per request and if you use nonces to secure your application with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) it would be inappropriate and insecure to include the a nonce value in the prerender itself. @@ -287,6 +289,31 @@ Suspense **无法** 检测在 Effect 或事件处理程序中获取的数据。 --- +### 中止预渲染 {/*aborting-prerendering*/} + +可以通过设置超时,来强制“终止”预渲染进程: + + +```js {2-5,11} +async function renderToString() { + const controller = new AbortController(); + setTimeout(() => { + controller.abort() + }, 10000); + + try { + // the prelude will contain all the HTML that was prerendered + // before the controller aborted. + const {prelude} = await prerender(, { + signal: controller.signal, + }); + //... +``` + +所有包含未完成子组件的 Suspense 边界都将以 fallback 状态包含在 prelude 中。 + +--- + ## 疑难解答 {/*troubleshooting*/} ### 我的流要等到整个应用渲染完成后才会启动。 {/*my-stream-doesnt-start-until-the-entire-app-is-rendered*/} diff --git a/src/content/reference/react-dom/static/prerenderToNodeStream.md b/src/content/reference/react-dom/static/prerenderToNodeStream.md index b5bb60eafe..fb8073ef07 100644 --- a/src/content/reference/react-dom/static/prerenderToNodeStream.md +++ b/src/content/reference/react-dom/static/prerenderToNodeStream.md @@ -58,7 +58,7 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to * **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML. * **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-outside-the-shell) or [not.](/reference/react-dom/server/renderToPipeableStream#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/renderToPipeableStream#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](/reference/react-dom/server/renderToPipeableStream#setting-the-status-code) before the shell is emitted. * **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) - * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort server rendering](/reference/react-dom/server/renderToPipeableStream#aborting-server-rendering) and render the rest on the client. + * **optional** `signal`: An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that lets you [abort prerendering](#aborting-prerendering) and render the rest on the client. #### Returns {/*returns*/} @@ -67,6 +67,10 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to - `prelude`: a [Node.js Stream.](https://nodejs.org/api/stream.html) of HTML. You can use this stream to send a response in chunks, or you can read the entire stream into a string. - If rendering fails, the Promise will be rejected. [Use this to output a fallback shell.](/reference/react-dom/server/renderToPipeableStream#recovering-from-errors-inside-the-shell) +#### Caveats {/*caveats*/} + +`nonce` is not an available option when prerendering. Nonces must be unique per request and if you use nonces to secure your application with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) it would be inappropriate and insecure to include the a nonce value in the prerender itself. + ### When should I use `prerenderToNodeStream`? {/*when-to-use-prerender*/} @@ -285,6 +289,30 @@ Suspense-enabled data fetching without the use of an opinionated framework is no --- +### Aborting prerendering {/*aborting-prerendering*/} + +You can force the prerender to "give up" after a timeout: + +```js {2-5,11} +async function renderToString() { + const controller = new AbortController(); + setTimeout(() => { + controller.abort() + }, 10000); + + try { + // the prelude will contain all the HTML that was prerendered + // before the controller aborted. + const {prelude} = await prerenderToNodeStream(, { + signal: controller.signal, + }); + //... +``` + +Any Suspense boundaries with incomplete children will be included in the prelude in the fallback state. + +--- + ## Troubleshooting {/*troubleshooting*/} ### My stream doesn't start until the entire app is rendered {/*my-stream-doesnt-start-until-the-entire-app-is-rendered*/}