useActionState
是一个 Hook,允许您根据表单操作的结果更新状态。
const [state, formAction] = useActionState(fn, initialState, permalink?);
参考
useActionState(action, initialState, permalink?)
在组件的顶层调用 useActionState
,以创建在调用表单操作时更新的组件状态。您需要向 useActionState
传递一个现有的表单操作函数以及一个初始状态,它会返回一个新的操作(您将在表单中使用该操作)以及最新的表单状态。最新的表单状态也会传递给您提供的函数。
import { useActionState } from "react";
async function increment(previousState, formData) {
return previousState + 1;
}
function StatefulForm({}) {
const [state, formAction] = useActionState(increment, 0);
return (
<form>
{state}
<button formAction={formAction}>Increment</button>
</form>
)
}
表单状态是上次提交表单时操作返回的值。如果表单尚未提交,则它就是您传递的初始状态。
如果与服务器操作一起使用,useActionState
允许在完成水合之前显示提交表单的服务器响应。
参数
fn
:提交表单或按下按钮时要调用的函数。调用该函数时,它将接收表单的先前状态(最初是您传递的initialState
,随后是其先前的返回值)作为其初始参数,然后是表单操作通常接收的参数。initialState
:您希望状态最初具有的值。它可以是任何可序列化的值。首次调用该操作后,将忽略此参数。- **可选**
permalink
:包含此表单修改的唯一页面 URL 的字符串。用于具有动态内容的页面(例如:feed)以及渐进增强:如果fn
是服务器操作并且在 JavaScript 包加载之前提交了表单,则浏览器将导航到指定的永久链接 URL,而不是当前页面的 URL。确保在目标页面上呈现相同的表单组件(包括相同的操作fn
和permalink
),以便 React 知道如何传递状态。表单水合后,此参数无效。
返回值
useActionState
返回一个包含两个值的数组
- 当前状态。在第一次渲染期间,它将与您传递的
initialState
匹配。调用操作后,它将与操作返回的值匹配。 - 您可以作为
action
属性传递给form
组件或作为formAction
属性传递给表单中任何button
组件的新操作。
注意事项
- 当与支持 React 服务器组件的框架一起使用时,
useActionState
允许您在客户端执行 JavaScript 之前使表单具有交互性。当在没有服务器组件的情况下使用时,它等同于组件本地状态。 - 传递给
useActionState
的函数接收一个额外的参数,即先前的或初始状态,作为其第一个参数。这使得它的签名与在不使用useActionState
的情况下直接用作表单操作时不同。
用法
使用表单操作返回的信息
在组件的顶层调用 useActionState
,以访问上次提交表单时操作的返回值。
import { useActionState } from 'react';
import { action } from './actions.js';
function MyComponent() {
const [state, formAction] = useActionState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}
useActionState
返回一个恰好包含两个项目的数组
- 表单的当前状态,最初设置为您提供的初始状态,并在提交表单后设置为您提供的操作的返回值。
- 您传递给
<form>
的新操作作为其action
属性。
当提交表单时,将调用您提供的操作函数。其返回值将成为表单的新的当前状态。
您提供的操作还将接收一个新的第一个参数,即表单的当前状态。第一次提交表单时,这将是您提供的初始状态,而在后续提交中,它将是上次调用操作时的返回值。其余的参数与未使用 useActionState
时相同。
function action(currentState, formData) {
// ...
return 'next state';
}
示例 1的 2: 显示表单错误
要显示消息(例如服务器操作返回的错误消息或 Toast),请将操作包装在对 useActionState
的调用中。
import { useActionState, useState } from "react"; import { addToCart } from "./actions.js"; function AddToCartForm({itemID, itemTitle}) { const [message, formAction] = useActionState(addToCart, null); return ( <form action={formAction}> <h2>{itemTitle}</h2> <input type="hidden" name="itemID" value={itemID} /> <button type="submit">Add to Cart</button> {message} </form> ); } export default function App() { return ( <> <AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" /> <AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" /> </> ) }