diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 060b974352..5da8560725 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -42,16 +42,10 @@ root.render( 严格模式启用了以下仅在开发环境下有效的行为: -<<<<<<< HEAD -- 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development),以查找由于非纯渲染而引起的错误。 -- 组件将 [重新运行 Effect 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 +- 组件将 [额外重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development) 以查找由于非纯渲染而引起的错误。 +- 组件将 [额外重新运行一次 Effect ](#fixing-bugs-found-by-re-running-effects-in-development) 以查找由于缺少 Effect 清理而引起的错误。 +- 组件将 [额外重新运行一次 refs 回调](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) 以查找由于缺少 ref 清理函数而引起的错误。 - 组件将被 [检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 -======= -- Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering. -- Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup. -- Your components will [re-run refs callbacks an extra time](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) to find bugs caused by missing ref cleanup. -- Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode) ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e #### 参数 {/*props*/} @@ -92,16 +86,10 @@ root.render( 严格模式启用了以下仅在开发环境下有效的行为: -<<<<<<< HEAD -- 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development),以查找由于非纯渲染而引起的错误。 -- 组件将 [重新运行 Effect 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 +- 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development) 以查找由于非纯渲染而引起的错误。 +- 组件将 [重新运行一次 Effect](#fixing-bugs-found-by-re-running-effects-in-development) 以查找由于缺少 Effect 清理而引起的错误。 +- 组件将 [额外重新运行一次 refs 回调](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) 以查找由于缺少 ref 清理函数而引起的错误。 - 组件将被 [检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 -======= -- Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering. -- Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup. -- Your components will [re-run ref callbacks an extra time](#fixing-bugs-found-by-cleaning-up-and-re-attaching-dom-refs-in-development) to find bugs caused by missing ref cleanup. -- Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode) ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e **所有这些检查仅在开发环境中进行,不会影响生产构建。** @@ -841,9 +829,6 @@ button { margin-left: 10px; } --- ### Fixing bugs found by re-running ref callbacks in development {/*fixing-bugs-found-by-re-running-ref-callbacks-in-development*/} -<<<<<<< HEAD -### 修复严格模式发出的弃用警告 {/*fixing-deprecation-warnings-enabled-by-strict-mode*/} -======= Strict Mode can also help find bugs in [callbacks refs.](/learn/manipulating-the-dom-with-refs) Every callback `ref` has some setup code and may have some cleanup code. Normally, React calls setup when the element is *created* (is added to the DOM) and calls cleanup when the element is *removed* (is removed from the DOM). @@ -1254,18 +1239,10 @@ Now on inital mount in StrictMode, the ref callbacks are all setup, cleaned up, Without Strict Mode, it was easy to miss the bug until you clicked around to app to notice broken features. Strict Mode made the bugs appear right away, before you push them to production. --- -### Fixing deprecation warnings enabled by Strict Mode {/*fixing-deprecation-warnings-enabled-by-strict-mode*/} ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +### 修复严格模式发出的弃用警告 {/*fixing-deprecation-warnings-enabled-by-strict-mode*/} React 会在任何一个位于 `` 树中的组件使用以下弃用 API 时发出警告: -<<<<<<< HEAD -* [`findDOMNode`](/reference/react-dom/findDOMNode),[请参考替代方案](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)。 * `UNSAFE_` 类生命周期方法,例如 [`UNSAFE_componentWillMount`](/reference/react/Component#unsafe_componentwillmount),[请参考替代方案](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles)。 -* 旧版上下文([`childContextTypes`](/reference/react/Component#static-childcontexttypes)、[`contextTypes`](/reference/react/Component#static-contexttypes) 和 [`getChildContext`](/reference/react/Component#getchildcontext)),[请参考替代方案](/reference/react/createContext)。 -* 旧版字符串引用([`this.refs`](/reference/react/Component#refs)),[请参考替代方案](https://reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)。 -======= -* `UNSAFE_` class lifecycle methods like [`UNSAFE_componentWillMount`](/reference/react/Component#unsafe_componentwillmount). [See alternatives.](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles) ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e 这些 API 主要用于旧版的 [类式组件](/reference/react/Component),因此在新版程序中很少出现。 diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 7ef34230de..265a877948 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -103,15 +103,7 @@ function Loading() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 -// 在实际的例子中,你可以尝试已经 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -124,34 +116,7 @@ export default function Albums({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/data.js hidden @@ -244,15 +209,9 @@ async function getAlbums() { **只有启用了 Suspense 的数据源才会激活 Suspense 组件**,它们包括: -<<<<<<< HEAD - 支持 Suspense 的框架如 [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) 和 [Next.js](https://nextjs.org/docs/getting-started/react-essentials)。 - 使用 [`lazy`](/reference/react/lazy) 懒加载组件代码。 -- 使用 [`use`](/reference/react/use) 读取 Promise 的值。 -======= -- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/getting-started/react-essentials) -- Lazy-loading component code with [`lazy`](/reference/react/lazy) -- Reading the value of a cached Promise with [`use`](/reference/react/use) ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +- 使用 [`use`](/reference/react/use) 读取缓存的 Promise 值。 Suspense **无法** 检测在 Effect 或事件处理程序中获取数据的情况。 @@ -347,15 +306,7 @@ export default function Panel({ children }) { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -364,49 +315,14 @@ export default function Biography({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Albums.js import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -419,34 +335,7 @@ export default function Albums({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/data.js hidden @@ -600,17 +489,10 @@ function Details({ artistId }) { 加载序列将会是: -<<<<<<< HEAD 1. 如果 `Biography` 没有加载完成,`BigSpinner` 会显示在整个内容区域的位置。 -1. 一旦 `Biography` 加载完成,`BigSpinner` 会被内容替换。 -1. 如果 `Albums` 没有加载完成,`AlbumsGlimmer` 会显示在 `Albums` 和它的父级 `Panel` 的位置。 -1. 最后,一旦 `Albums` 加载完成,它会替换 `AlbumsGlimmer`。 -======= -1. If `Biography` hasn't loaded yet, `BigSpinner` is shown in place of the entire content area. -2. Once `Biography` finishes loading, `BigSpinner` is replaced by the content. -3. If `Albums` hasn't loaded yet, `AlbumsGlimmer` is shown in place of `Albums` and its parent `Panel`. -4. Finally, once `Albums` finishes loading, it replaces `AlbumsGlimmer`. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +2. 一旦 `Biography` 加载完成,`BigSpinner` 会被内容替换。 +3. 如果 `Albums` 没有加载完成,`AlbumsGlimmer` 会显示在 `Albums` 和它的父级 `Panel` 的位置。 +4. 最后,一旦 `Albums` 加载完成,它会替换 `AlbumsGlimmer`。 @@ -690,15 +572,7 @@ export default function Panel({ children }) { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -707,49 +581,14 @@ export default function Biography({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Albums.js import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -762,34 +601,7 @@ export default function Albums({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/data.js hidden @@ -956,15 +768,7 @@ export default function App() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 稳定版本中可用 -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function SearchResults({ query }) { if (query === '') { return null; @@ -983,34 +787,7 @@ export default function SearchResults({ query }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/data.js hidden @@ -1177,15 +954,7 @@ export default function App() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function SearchResults({ query }) { if (query === '') { return null; @@ -1204,34 +973,7 @@ export default function SearchResults({ query }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/data.js hidden @@ -1455,15 +1197,7 @@ function AlbumsGlimmer() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -1476,49 +1210,14 @@ export default function Albums({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Biography.js import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -1527,34 +1226,7 @@ export default function Biography({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Panel.js @@ -1841,15 +1513,7 @@ function AlbumsGlimmer() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -1862,49 +1526,14 @@ export default function Albums({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Biography.js import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -1913,34 +1542,7 @@ export default function Biography({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Panel.js @@ -2226,15 +1828,7 @@ function AlbumsGlimmer() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 - -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Albums({ artistId }) { const albums = use(fetchData(`/${artistId}/albums`)); return ( @@ -2247,49 +1841,14 @@ export default function Albums({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Biography.js import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:这个组件使用了一个实验性的 API -// 该 API 并未在 React 的稳定版本中可用 -// 对于一个现实的例子,你可以尝试一个 -// 与 Suspense 集成的框架,例如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function Biography({ artistId }) { const bio = use(fetchData(`/${artistId}/bio`)); return ( @@ -2298,34 +1857,7 @@ export default function Biography({ artistId }) { ); } -<<<<<<< HEAD - -// 这是一个解决 bug 的临时方案,以便让演示运行起来。 -// TODO:当 bug 修复后,用真正的实现替换。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e + ``` ```js src/Panel.js diff --git a/src/content/reference/react/cache.md b/src/content/reference/react/cache.md index 8204f8b73b..ea5b60fd09 100644 --- a/src/content/reference/react/cache.md +++ b/src/content/reference/react/cache.md @@ -3,19 +3,11 @@ title: cache canary: true --- -<<<<<<< HEAD - -* `cache` 仅供与 [React 服务器组件](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) 一起使用。请参阅支持 React 服务器组件的 [框架](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)。 - -* `cache` 仅在 React 的 [Canary](/community/versioning-policy#canary-channel) 和 [experimental](/community/versioning-policy#experimental-channel) 渠道中可用。在将 `cache` 用于生产环境之前,请确保了解其限制。查看此处了解有关 [React 发布渠道的更多信息](/community/versioning-policy#all-release-channels)。 - -======= +* `cache` 仅供与 [React 服务器组件](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) 一起使用。 -`cache` is only for use with [React Server Components](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components). - +* `cache` 仅在 React 的 [Canary](/community/versioning-policy#canary-channel) 和 [experimental](/community/versioning-policy#experimental-channel) 渠道中可用。在将 `cache` 用于生产环境之前,请确保了解其限制。查看此处了解有关 [React 发布渠道的更多信息](/community/versioning-policy#all-release-channels)。 ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e diff --git a/src/content/reference/react/createElement.md b/src/content/reference/react/createElement.md index 4d0147263e..f192761aab 100644 --- a/src/content/reference/react/createElement.md +++ b/src/content/reference/react/createElement.md @@ -48,17 +48,10 @@ function Greeting({ name }) { `createElement` 返回一个 React 元素,它有这些属性: -<<<<<<< HEAD * `type`:你传入的 `type`。 -* `props`:你传入的 `props`,不包括 `ref` 和 `key`。如果 `type` 是一个组件,且带有过时的 `type.defaultProps` 属性,那么 `props` 中任何缺失或未定义的字段都会采用 `type.defaultProps` 中的值。 +* `props`:你传入的 `props`,不包括 `ref` 和 `key`。 * `ref`:你传入的 `ref`。如果缺失则为 `null`。 * `key`:你传入的 `key`,会被强制转换为字符串。如果缺失则为 `null`。 -======= -* `type`: The `type` you have passed. -* `props`: The `props` you have passed except for `ref` and `key`. -* `ref`: The `ref` you have passed. If missing, `null`. -* `key`: The `key` you have passed, coerced to a string. If missing, `null`. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e 通常你会在你组件的最后返回这个元素,或者把它作为另一个元素的子元素。虽然你可以读取元素的属性,但你最好把创建的元素作为黑盒,只用于渲染。 diff --git a/src/content/reference/react/experimental_taintUniqueValue.md b/src/content/reference/react/experimental_taintUniqueValue.md index e3016e66aa..7cc0516556 100644 --- a/src/content/reference/react/experimental_taintUniqueValue.md +++ b/src/content/reference/react/experimental_taintUniqueValue.md @@ -192,11 +192,7 @@ experimental_taintUniqueValue( ); ``` -<<<<<<< HEAD -现在无论何时有人试图将此密码传递给客户端组件,或者通过服务器操作将密码发送给客户端组件时都会引发一个错误,错误消息则是在调用 `taintUniqueValue` 时定义的。 -======= -Now whenever anyone tries to pass this password to a Client Component, or send the password to a Client Component with a Server Function, an error will be thrown with message you defined when you called `taintUniqueValue`. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +现在无论何时有人试图将此密码传递给客户端组件,或者通过服务器函数将密码发送给客户端组件时都会引发一个错误,错误消息则是在调用 `taintUniqueValue` 时定义的。 diff --git a/src/content/reference/react/legacy.md b/src/content/reference/react/legacy.md index a829ba17fb..ce747122f2 100644 --- a/src/content/reference/react/legacy.md +++ b/src/content/reference/react/legacy.md @@ -12,46 +12,25 @@ title: "过时的 React API" ## 过时的 API {/*legacy-apis*/} -<<<<<<< HEAD * [`Children`](/reference/react/Children) 允许你处理和转化作为 `children` 的 JSX。[查看替代方案](/reference/react/Children#alternatives)。 * [`cloneElement`](/reference/react/cloneElement) 允许你使用一个元素作为初始值创建一个新的 React 元素。[查看替代方案](/reference/react/cloneElement#alternatives)。 * [`Component`](/reference/react/Component) 允许你定义一个 JavaScript class 作为 React 类式组件。[查看替代方案](/reference/react/Component#alternatives)。 * [`createElement`](/reference/react/createElement) 允许你创建一个 React 元素,但是一般会使用 JSX。 * [`createRef`](/reference/react/createRef) 允许你创建一个可以包含任何值的 ref 对象。[查看替代方案](/reference/react/createRef#alternatives)。 +* [`forwardRef`](/reference/react/forwardRef) 允许你使用 [ref](/learn/manipulating-the-dom-with-refs) 将 DOM 节点暴露给父组件。 * [`isValidElement`](/reference/react/isValidElement) 检测参数值是否为 React 元素,通常会与 [`cloneElement`.](/reference/react/cloneElement) 一起使用。 * [`PureComponent`](/reference/react/PureComponent) 与 [`Component`](/reference/react/Component) 类似,但是当 props 相同时会跳过重新渲染。[查看替代方案](/reference/react/PureComponent#alternatives)。 -======= -* [`Children`](/reference/react/Children) lets you manipulate and transform the JSX received as the `children` prop. [See alternatives.](/reference/react/Children#alternatives) -* [`cloneElement`](/reference/react/cloneElement) lets you create a React element using another element as a starting point. [See alternatives.](/reference/react/cloneElement#alternatives) -* [`Component`](/reference/react/Component) lets you define a React component as a JavaScript class. [See alternatives.](/reference/react/Component#alternatives) -* [`createElement`](/reference/react/createElement) lets you create a React element. Typically, you'll use JSX instead. -* [`createRef`](/reference/react/createRef) creates a ref object which can contain arbitrary value. [See alternatives.](/reference/react/createRef#alternatives) -* [`forwardRef`](/reference/react/forwardRef) lets your component expose a DOM node to parent component with a [ref.](/learn/manipulating-the-dom-with-refs) -* [`isValidElement`](/reference/react/isValidElement) checks whether a value is a React element. Typically used with [`cloneElement`.](/reference/react/cloneElement) -* [`PureComponent`](/reference/react/PureComponent) is similar to [`Component`,](/reference/react/Component) but it skip re-renders with same props. [See alternatives.](/reference/react/PureComponent#alternatives) ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e ---- - -<<<<<<< HEAD -## 已弃用的 API {/*deprecated-apis*/} -======= -## Removed APIs {/*removed-apis*/} ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e -These APIs were removed in React 19: +--- -<<<<<<< HEAD -这些 API 将在未来的 React 主要版本中被移除。 +## 已移除的 API {/*removed-apis*/} - +这些 API 在 React 19 中被移除。 -* [`createFactory`](/reference/react/createFactory) 可以创建一个能够生成指定类型 React 元素的函数。 -======= -* [`createFactory`](https://18.react.dev/reference/react/createFactory): use JSX instead. -* Class Components: [`static contextTypes`](https://18.react.dev//reference/react/Component#static-contexttypes): use [`static contextType`](#static-contexttype) instead. -* Class Components: [`static childContextTypes`](https://18.react.dev//reference/react/Component#static-childcontexttypes): use [`static contextType`](#static-contexttype) instead. -* Class Components: [`static getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): use [`Context.Provider`](/reference/react/createContext#provider) instead. -* Class Components: [`static propTypes`](https://18.react.dev//reference/react/Component#static-proptypes): use a type system like [TypeScript](https://www.typescriptlang.org/) instead. -* Class Components: [`this.refs`](https://18.react.dev//reference/react/Component#refs): use [`createRef`](/reference/react/createRef) instead. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +* [`createFactory`](https://18.react.dev/reference/react/createFactory):使用 JSX 来替代。 +* 类组件:[`static contextTypes`](https://18.react.dev//reference/react/Component#static-contexttypes): 使用 [`static contextType`](#static-contexttype) 来替代。 +* 类组件:[`static childContextTypes`](https://18.react.dev//reference/react/Component#static-childcontexttypes): 使用 [`static contextType`](#static-contexttype) 来替代。 +* 类组件:[`static getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): 使用 [`Context.Provider`](/reference/react/createContext#provider) 来替代。 +* 类组件:[`static propTypes`](https://18.react.dev//reference/react/Component#static-proptypes): 使用 [TypeScript](https://www.typescriptlang.org/) 等类型系统来替代。 +* 类组件:[`this.refs`](https://18.react.dev//reference/react/Component#refs): 使用 [`createRef`](/reference/react/createRef) 来替代。 diff --git a/src/content/reference/react/startTransition.md b/src/content/reference/react/startTransition.md index f94747a96d..67720446f5 100644 --- a/src/content/reference/react/startTransition.md +++ b/src/content/reference/react/startTransition.md @@ -6,11 +6,7 @@ translators: -<<<<<<< HEAD -`startTransition` 可以让你在不阻塞 UI 的情况下更新 state。 -======= -`startTransition` lets you render a part of the UI in the background. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +`startTransition` 可以让你在后台渲染 UI 的一部分。 ```js startTransition(action) @@ -47,11 +43,7 @@ function TabContainer() { #### 参数 {/*parameters*/} -<<<<<<< HEAD -* `scope`:调用一个或多个 [`set` 函数](/reference/react/useState#setstate) 来更新 state 的函数。React 会立即调用没有参数的 `scope`,并将在 `scope` 函数调用期间,调度所有的 state,并将同步更新标记为 transition。它们是 [非阻塞的](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition),并且 [不会显示不想要的加载提示](/reference/react/useTransition#preventing-unwanted-loading-indicators)。 -======= -* `action`: A function that updates some state by calling one or more [`set` functions](/reference/react/useState#setstate). React calls `action` immediately with no parameters and marks all state updates scheduled synchronously during the `action` function call as Transitions. Any async calls awaited in the `action` will be included in the transition, but currently require wrapping any `set` functions after the `await` in an additional `startTransition` (see [Troubleshooting](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). State updates marked as Transitions will be [non-blocking](#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](#preventing-unwanted-loading-indicators). ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +* `action`:调用一个或多个 [`set` 函数](/reference/react/useState#setstate)来更新 state 的函数。React 会立即调用没有参数的 `action`,并将在 `action` 函数调用期间,调度所有的 state,并将同步更新标记为 transition。任何在 `action` 中等待的异步调用都将包含在 transition 中,但是目前需要将 `await` 之后的任何 `set` 函数包装在 `startTransition` 中 (查看 [故障排除](#react-doesnt-treat-my-state-update-after-await-as-a-transition) 了解更多)。被标记为 Transitions 的状态更新是 [非阻塞的](#marking-a-state-update-as-a-non-blocking-transition),并且 [不会显示不想要的加载提示](#preventing-unwanted-loading-indicators)。 #### 返回值 {/*returns*/} @@ -63,23 +55,15 @@ function TabContainer() { * 只有当你能访问某个 state 的 `set` 函数时,你才能将它的更新包裹到 Transition 中。如果你想根据 props 或自定义 Hook 的返回值来启动一个 transition,请尝试使用 [`useDeferredValue`](/reference/react/useDeferredValue)。 -<<<<<<< HEAD -* 你传递给 `startTransition` 的函数必须是同步的。React 会立即执行此函数,将其执行期间发生的所有 state 更新标记为 transition。如果你想试着稍后执行更多的 state 更新(例如,在 timeout 中),它们不会被标记为转换。 -======= -* The function you pass to the of `startTransition` is called immediately, marking all state updates that happen while it executes as Transitions. If you try to perform state updates in a `setTimeout`, for example, they won't be marked as Transitions. +* 你传递给 `startTransition` 的函数会立即被调用,并将其执行时发生的所有状态更新标记为 Transitions。如果你试图在 `setTimeout` 中进行状态更新,它们将不会被标记为 Transitions。 * You must wrap any state updates after any async requests in another `startTransition` to mark them as Transitions. This is a known limitation that we will fix in the future (see [Troubleshooting](#react-doesnt-treat-my-state-update-after-await-as-a-transition)). ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e * 一个被标记为 Transition 的 state 更新时将会被其他 state 更新打断。例如,如果你在 Transition 内部更新图表组件,但在图表重新渲染时在输入框中打字,则 React 将先处理输入 state 更新,之后才会重新启动对图表组件的渲染工作。 * Transition 更新不能用于控制文本输入。 -<<<<<<< HEAD -* 如果有多个正在进行的 transition,当前 React 会将它们集中在一起处理。这是一个限制,在未来的版本中可能会被移除。 -======= -* If there are multiple ongoing Transitions, React currently batches them together. This is a limitation that may be removed in a future release. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +* 如果有多个正在进行的 transition,目前 React 会将它们集中在一起处理。这是一个限制,在未来的版本中可能会被移除。 --- diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index d2bf91655b..636a49f702 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -2,15 +2,7 @@ title: use --- -<<<<<<< HEAD - -`use` API 仅在 Canary 与 experimental 渠道中可用。参阅 [React 发布渠道](/community/versioning-policy#all-release-channels) 以了解更多信息。 - - - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e `use` 是一个 React API,它可以让你读取类似于 [Promise](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise) 或 [context](/learn/passing-data-deeply-with-context) 的资源的值。 @@ -56,15 +48,9 @@ function MessageComponent({ messagePromise }) { #### 注意 {/*caveats*/} -<<<<<<< HEAD * `use` API 必须在组件或 Hook 内部调用。 -* 在 [服务器组件](/reference/rsc/use-server) 中获取数据时,应优先使用 `async` 和 `await` 而不是 `use`。`async` 和 `await` 会从调用 `await` 的点开始渲染,而 `use` 会在数据获取到后重新渲染组件。 -* 在 [服务器组件](/reference/rsc/use-server) 中创建 Promise 并将其传递给 [客户端组件](/reference/rsc/use-client) 优于在客户端组件中创建 Promise。在客户端组件中创建的 Promise 每次渲染都会重新创建。从服务器组件传递到客户端组件的 Promise 在重新渲染时保持稳定。[请参阅此示例](#streaming-data-from-server-to-client)。 -======= -* The `use` API must be called inside a Component or a Hook. -* When fetching data in a [Server Component](/reference/rsc/server-components), prefer `async` and `await` over `use`. `async` and `await` pick up rendering from the point where `await` was invoked, whereas `use` re-renders the component after the data is resolved. -* Prefer creating Promises in [Server Components](/reference/rsc/server-components) and passing them to [Client Components](/reference/rsc/use-client) over creating Promises in Client Components. Promises created in Client Components are recreated on every render. Promises passed from a Server Component to a Client Component are stable across re-renders. [See this example](#streaming-data-from-server-to-client). ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +* 在 [服务器组件](/reference/rsc/server-components) 中获取数据时,应优先使用 `async` 和 `await` 而不是 `use`。`async` 和 `await` 会从调用 `await` 的点开始渲染,而 `use` 会在数据获取到后重新渲染组件。 +* 在 [服务器组件](/reference/rsc/server-components) 中创建 Promise 并将其传递给 [客户端组件](/reference/rsc/use-client) 优于在客户端组件中创建 Promise。在客户端组件中创建的 Promise 每次渲染都会重新创建。从服务器组件传递到客户端组件的 Promise 在重新渲染时保持稳定。[请参阅此示例](#streaming-data-from-server-to-client)。 --- @@ -288,12 +274,6 @@ export default function App() { ``` ```js src/index.js hidden -<<<<<<< HEAD -// TODO: 在稳定版本中更新 import -// 以替代此处 canary 版本中的导入方式,一旦 `use` -// API 在 React 稳定版本中发布 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -401,12 +381,6 @@ export default function App() { ``` ```js src/index.js hidden -<<<<<<< HEAD -// TODO: 在稳定版本中更新 import -// 以替代此处 canary 版本中的导入方式,一旦 `use` -// API 在 React 稳定版本中发布 -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; diff --git a/src/content/reference/react/useActionState.md b/src/content/reference/react/useActionState.md index 6588809d6b..2ad3c60e65 100644 --- a/src/content/reference/react/useActionState.md +++ b/src/content/reference/react/useActionState.md @@ -2,21 +2,6 @@ title: useActionState --- -<<<<<<< HEAD - - -`useActionState` Hook 当前仅在 React Canary 与 experimental 渠道中可用。请点此了解更多关于 [React 发布渠道](/community/versioning-policy#all-release-channels) 的信息。此外,需要一款完全支持 [React 服务器组件](/reference/react/use-client) 特性的框架才可以使用 `useActionState` 的所有特性。 - - - - - -In earlier React Canary versions, this API was part of React DOM and called `useFormState`. - - - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e `useActionState` 是一个可以根据某个表单动作的结果更新 state 的 Hook。 @@ -29,7 +14,7 @@ const [state, formAction, isPending] = useActionState(fn, initialState, permalin -In earlier React Canary versions, this API was part of React DOM and called `useFormState`. +在早期的 React Canary 版本中,此 API 是 React DOM 的一部分,称为 `useFormState`。 @@ -66,27 +51,16 @@ function StatefulForm({}) { form state 是一个只在表单被提交触发 action 后才会被更新的值。如果该表单没有被提交,该值会保持传入的初始值不变。 -<<<<<<< HEAD -如果配合 Server Action 一起使用,`useActionState` 允许与表单交互的服务器的返回值在激活完成前显示。 -======= -If used with a Server Function, `useActionState` allows the server's response from submitting the form to be shown even before hydration has completed. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +如果与服务器函数一起使用,`useActionState` 允许与表单交互的服务器的返回值在激活完成前显示。 [请参阅下方更多示例](#usage)。 -<<<<<<< HEAD #### 参数 {/*parameters*/} -======= -#### Parameters {/*parameters*/} - -* `fn`: The function to be called when the form is submitted or button pressed. When the function is called, it will receive the previous state of the form (initially the `initialState` that you pass, subsequently its previous return value) as its initial argument, followed by the arguments that a form action normally receives. -* `initialState`: The value you want the state to be initially. It can be any serializable value. This argument is ignored after the action is first invoked. -* **optional** `permalink`: A string containing the unique page URL that this form modifies. For use on pages with dynamic content (eg: feeds) in conjunction with progressive enhancement: if `fn` is a [server function](/reference/rsc/server-functions) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL, rather than the current page's URL. Ensure that the same form component is rendered on the destination page (including the same action `fn` and `permalink`) so that React knows how to pass the state through. Once the form has been hydrated, this parameter has no effect. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e * `fn`:当按钮被按下或者表单被提交时触发的函数。当函数被调用时,该函数会接收到表单的上一个 state(初始值为传入的 `initialState` 参数,否则为上一次执行完该函数的结果)作为函数的第一个参数,余下参数为普通表单动作接到的参数。 * `initialState`:state 的初始值。任何可序列化的值都可接收。当 action 被调用一次后该参数会被忽略。 -* **可选** `permalink`: A string containing the unique page URL that this form modifies. For use on pages with dynamic content (eg: feeds) in conjunction with progressive enhancement: if `fn` is a [server action](/reference/react/use-server) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL, rather than the current page's URL. Ensure that the same form component is rendered on the destination page (including the same action `fn` and `permalink`) so that React knows how to pass the state through. Once the form has been hydrated, this parameter has no effect. +* **可选的** `permalink`: A string containing the unique page URL that this form modifies. For use on pages with dynamic content (eg: feeds) in conjunction with progressive enhancement: if `fn` is a [server function](/reference/rsc/server-functions) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL, rather than the current page's URL. Ensure that the same form component is rendered on the destination page (including the same action `fn` and `permalink`) so that React knows how to pass the state through. Once the form has been hydrated, this parameter has no effect. + {/* TODO T164397693: link to serializable values docs once it exists */} #### 返回值 {/*returns*/} @@ -146,11 +120,7 @@ function action(currentState, formData) { #### 展示表单错误 {/*display-form-errors*/} -<<<<<<< HEAD -将 action 包裹进 `useActionState` 即可展示诸如错误信息或 Server Action 返回的 toast 等信息。 -======= -To display messages such as an error message or toast that's returned by a Server Function, wrap the action in a call to `useActionState`. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +将 action 包裹进 `useActionState` 即可展示诸如错误信息或服务器函数返回的 toast 等信息。 @@ -214,11 +184,7 @@ form button { #### 提交表单后展示结构性数据 {/*display-structured-information-after-submitting-a-form*/} -<<<<<<< HEAD -Server Actions 的返回值可以为任意可序列化的值。例如,可以返回一个实例,该实例携带一个 boolean 类型的属性表示操作是否成功,同时附带错误信息或更新消息。 -======= -The return value from a Server Function can be any serializable value. For example, it could be an object that includes a boolean indicating whether the action was successful, an error message, or updated information. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +服务器函数的返回值可以为任意可序列化的值。例如,可以返回一个实例,该实例携带一个 boolean 类型的属性表示操作是否成功,同时附带错误信息或更新消息。 diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index 01313157a0..036c65b880 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -36,29 +36,13 @@ function SearchPage() { #### 参数 {/*parameters*/} -<<<<<<< HEAD * `value`: 你想延迟的值,可以是任何类型。 -* **可选的** `initialValue`: 组件初始渲染时使用的值。如果省略此选项,`useDeferredValue` 在初始渲染期间不会延迟,因为没有以前的版本可以渲染。 -======= -* `value`: The value you want to defer. It can have any type. -* **optional** `initialValue`: A value to use during the initial render of a component. If this option is omitted, `useDeferredValue` will not defer during the initial render, because there's no previous version of `value` that it can render instead. ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +* **可选的** `initialValue`: 组件初始渲染时使用的值。如果省略此选项,`useDeferredValue` 在初始渲染期间不会延迟,因为没有以前的版本可以渲染。 -#### 返回值 {/*returns*/} - -<<<<<<< HEAD -- `currentValue`: 在初始渲染期间,返回的延迟值将与你提供的值相同。在更新期间,React 首先尝试使用旧值重新渲染(因此返回旧值),然后在后台尝试使用新值重新渲染(因此返回更新后的值)。 - - -在最新的 React Canary 版本中,`useDeferredValue` 在初始渲染期间返回 `initialValue`,并在后台使用返回的 `value` 重新调度渲染。 - - -======= -#### Returns {/*returns*/} +#### 返回值 {/*returns*/} -- `currentValue`: During the initial render, the returned deferred value will be the `initialValue`, or the same as the value you provided. During updates, React will first attempt a re-render with the old value (so it will return the old value), and then try another re-render in the background with the new value (so it will return the updated value). ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e +- `currentValue`: 在初始渲染期间,返回的延迟值是 `initialValue` 或你提供的值。在更新期间,React 首先尝试使用旧值重新渲染(因此返回旧值),然后在后台尝试使用新值重新渲染(因此返回更新后的值)。 #### 注意事项 {/*caveats*/} @@ -141,15 +125,6 @@ export default function App() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:此组件使用了一种实验性 API -// 该 API 尚未在稳定版本的 React 中发布。 - -// 如果想找实际的例子,可以尝试一个 -// 已经集成了 suspense 的框架,比如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function SearchResults({ query }) { if (query === '') { return null; @@ -168,34 +143,6 @@ export default function SearchResults({ query }) { ); } -<<<<<<< HEAD - -// 这是一个解决演示中的一个 bug 的临时实现。 -// TODO:待 bug 修复后替换为真正的实现。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e ``` ```js src/data.js hidden @@ -348,15 +295,6 @@ export default function App() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:此组件使用了一种实验性 API -// 该 API 尚未在稳定版本的 React 中发布。 - -// 如果想找实际的例子,可以尝试一个 -// 已经集成了 suspense 的框架,比如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function SearchResults({ query }) { if (query === '') { return null; @@ -375,34 +313,6 @@ export default function SearchResults({ query }) { ); } -<<<<<<< HEAD - -// 这是一个解决演示中的一个 bug 的临时实现。 -// TODO:待 bug 修复后应该替换为真正的实现。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e ``` ```js src/data.js hidden @@ -569,15 +479,6 @@ export default function App() { import {use} from 'react'; import { fetchData } from './data.js'; -<<<<<<< HEAD -// 注意:此组件使用了一种实验性 API -// 该 API 尚未在稳定版本的 React 中发布。 - -// 如果想找实际的例子,可以尝试一个 -// 已经集成了 suspense 的框架,比如 Relay 或 Next.js。 - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e export default function SearchResults({ query }) { if (query === '') { return null; @@ -596,34 +497,6 @@ export default function SearchResults({ query }) { ); } -<<<<<<< HEAD - -// 这是一个解决演示中的一个 bug 的临时实现。 -// TODO:待 bug 修复后应该替换为真正的实现。 -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e ``` ```js src/data.js hidden diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 899d8f4c6f..f9ba3849bc 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -2,15 +2,6 @@ title: useOptimistic --- -<<<<<<< HEAD - - -`useOptimistic` Hook 仅在 Canary 与 experimental 渠道中可用。参阅 [React 发布渠道](/community/versioning-policy#all-release-channels) 以了解更多信息。 - - - -======= ->>>>>>> 69edd845b9a654c6ac9ed68da19d5b42897e636e `useOptimistic` 是一个 React Hook,它可以帮助你更乐观地更新用户界面。