diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index a4ce793bff..2d5856f3d1 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -19,12 +19,10 @@ title: React Compiler -React Compiler 是一个新的实验性编译器,我们已经开源,以便从社区中获得早期反馈。它仍然存在一些问题,还没有完全准备好投入生产。 - -React Compiler 需要 React 19 RC。如果你无法升级到 React 19,你可以尝试 userspace 实现缓存功能,如 [工作组](https://github.com/reactwg/react-compiler/discussions/6) 中所述。但请注意,这并不推荐,你应尽可能升级到 React 19。 +React Compiler 是一个新的实验性编译器,我们已经将其开源,以便从社区中获得早期反馈。它仍然存在一些问题,所以还没有完全准备好投入生产。 -React Compiler 是一个新的实验性编译器,我们已经开源以获得社区的早期反馈。它是一个仅在构建时使用的工具,可以自动优化你的 React 应用程序。它可以与纯 JavaScript 一起使用,并且了解 [React 规则](/reference/rules),因此你无需重写任何代码即可使用它。 +React Compiler 是一个新的实验性编译器,我们已经将其开源,以便从社区中获得早期反馈。它是一个仅在构建时使用的工具,可以自动优化你的 React 应用程序。它可以与纯 JavaScript 一起使用,并且了解 [React 规则](/reference/rules),因此你无需重写任何代码即可使用它。 编译器还包括一个 [ESLint 插件](#installing-eslint-plugin-react-compiler),可以在你的编辑器中直接显示编译器的分析结果。该插件独立运行,即使你的应用程序中没有使用编译器也可以使用。我们建议所有 React 开发人员使用这个 ESLint 插件来帮助提高代码库的质量。 @@ -226,6 +224,29 @@ module.exports = function () { `babel-plugin-react-compiler` 应该在其他 Babel 插件之前运行,因为编译器需要输入源信息进行声音分析。 +React Compiler 与 React 19 RC 配合使用效果最佳。如果你无法升级,可以安装额外的 `react-compiler-runtime` 包来编译代码并在 19 之前的版本上运行。 但请注意,支持的最低版本是 17。 + + +npm install react-compiler-runtime@experimental + + +你还应该在编译器配置中添加正确的 `target`,值为你所使用的 React 大版本。 + +```js {3} +// babel.config.js +const ReactCompilerConfig = { + target: '18' // '17' | '18' | '19' +}; + +module.exports = function () { + return { + plugins: [ + ['babel-plugin-react-compiler', ReactCompilerConfig], + ], + }; +}; +``` + ### Vite {/*usage-with-vite*/} 如果你使用 Vite,你可以将插件添加到 vite-plugin-react 中: diff --git a/src/content/reference/react/useActionState.md b/src/content/reference/react/useActionState.md index 9abe84e749..f10220f4be 100644 --- a/src/content/reference/react/useActionState.md +++ b/src/content/reference/react/useActionState.md @@ -20,7 +20,7 @@ In earlier React Canary versions, this API was part of React DOM and called `use `useActionState` 是一个可以根据某个表单动作的结果更新 state 的 Hook。 ```js -const [state, formAction] = useActionState(fn, initialState, permalink?); +const [state, formAction, isPending] = useActionState(fn, initialState, permalink?); ``` @@ -35,7 +35,7 @@ const [state, formAction] = useActionState(fn, initialState, permalink?); {/* TODO T164397693: link to actions documentation once it exists */} -在组件的顶层调用 `useActionState` 即可创建一个随 [表单动作被调用](/reference/react-dom/components/form) 而更新的 state。在调用 `useActionState` 时在参数中传入现有的表单动作函数以及一个初始状态,它就会返回一个新的 action 函数和一个 form state 以供在 form 中使用。这个新的 form state 也会作为参数传入提供的表单动作函数。 +在组件的顶层调用 `useActionState` 即可创建一个随 [表单动作被调用](/reference/react-dom/components/form) 而更新的 state。在调用 `useActionState` 时在参数中传入现有的表单动作函数以及一个初始状态,无论 Action 是否在 pending 中,它都会返回一个新的 action 函数和一个 form state 以供在 form 中使用。这个新的 form state 也会作为参数传入提供的表单动作函数。 ```js import { useActionState } from "react"; @@ -70,10 +70,11 @@ form state 是一个只在表单被提交触发 action 后才会被更新的值 #### 返回值 {/*returns*/} -`useActionState` 返回一个包含两个值的数组: +`useActionState` 返回一个包含以下值的数组: 1. 当前的 state。第一次渲染期间,该值为传入的 `initialState` 参数值。在 action 被调用后该值会变为 action 的返回值。 2. 一个新的 action 函数用于在你的 `form` 组件的 `action` 参数或表单中任意一个 `button` 组件的 `formAction` 参数中传递。 +3. 一个 `isPending` 标识,用于表明是否有正在 pending 的 Transition。 #### 注意 {/*caveats*/} @@ -103,10 +104,11 @@ function MyComponent() { } ``` -`useActionState` 返回一个包含两个值的数组: +`useActionState` 返回一个包含以下值的数组: 1. 该表单的 当前 state,初始值为提供的 初始 state,当表单被提交后则改为传入的 action 的返回值。 2. 传入 `
` 标签的 `action` 属性的 新 action。 +3. 一个 pending state,可以在处理 action 的过程中使用它。 表单被提交后,传入的 action 函数会被执行。返回值将会作为该表单的新的 当前 state。 @@ -132,13 +134,13 @@ import { useActionState, useState } from "react"; import { addToCart } from "./actions.js"; function AddToCartForm({itemID, itemTitle}) { - const [message, formAction] = useActionState(addToCart, null); + const [message, formAction, isPending] = useActionState(addToCart, null); return (

{itemTitle}

- {message} + {isPending ? "加载中……" : message}
); } @@ -161,6 +163,10 @@ export async function addToCart(prevState, queryData) { if (itemID === "1") { return "已加入购物车"; } else { + // 认为添加延迟以使等待更明显。 + await new Promise(resolve => { + setTimeout(resolve, 2000); + }); return "无法加入购物车:商品已售罄"; } }