useActionState
是一个可以根据某个表单动作的结果更新 state 的 Hook。
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
参考
useActionState(action, initialState, permalink?)
在组件的顶层调用 useActionState
即可创建一个随 表单动作被调用 而更新的 state。在调用 useActionState
时在参数中传入现有的表单动作函数以及一个初始状态,无论 Action 是否在 pending 中,它都会返回一个新的 action 函数和一个 form state 以供在 form 中使用。这个新的 form state 也会作为参数传入提供的表单动作函数。
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}>+1</button>
</form>
)
}
form state 是一个只在表单被提交触发 action 后才会被更新的值。如果该表单没有被提交,该值会保持传入的初始值不变。
如果与服务器函数一起使用,useActionState
允许与表单交互的服务器的返回值在激活完成前显示。
参数
fn
:当按钮被按下或者表单被提交时触发的函数。当函数被调用时,该函数会接收到表单的上一个 state(初始值为传入的initialState
参数,否则为上一次执行完该函数的结果)作为函数的第一个参数,余下参数为普通表单动作接到的参数。initialState
:state 的初始值。任何可序列化的值都可接收。当 action 被调用一次后该参数会被忽略。- 可选的
permalink
:一个包含了在特定情况下(后述)表单提交后将跳转到的独立 URL 的字符串。此参数用于渐进式地增强应用了动态内容的页面(例如 feeds):如果fn
是一个 服务器函数,并且表单在 JavaScript 包加载之前提交,则浏览器将导航到指定的permalink
URL,而不是当前页面的 URL。确保在目标页面上渲染相同的表单组件(包括相同的fn
和permalink
),以便 React 知道应如何同步状态。一旦表单被激活,此参数将不再起作用。
返回值
useActionState
返回一个包含以下值的数组:
- 当前的 state。第一次渲染期间,该值为传入的
initialState
参数值。在 action 被调用后该值会变为 action 的返回值。 - 一个新的 action 函数用于在你的
form
组件的action
参数或表单中任意一个button
组件的formAction
参数中传递。这个 action 也可以手动在startTransition
中调用。 - 一个
isPending
标识,用于表明是否有正在 pending 的 Transition。
注意
- 在支持 React 服务器组件的框架中使用该功能时,
useActionState
允许表单在服务器渲染阶段时获得部分交互性。当不使用服务器组件时,它的特性与本地 state 相同。 - 与直接通过表单动作调用的函数不同,传入
useActionState
的函数被调用时,会多传入一个代表 state 的上一个值或初始值的参数作为该函数的第一个参数。
用法
使用某个表单动作返回的信息
在组件的顶层调用 useActionState
以获取上一次表单被提交时触发的 action 的返回值。
import { useActionState } from 'react';
import { action } from './actions.js';
function MyComponent() {
const [state, formAction] = useActionState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}
useActionState
返回一个包含以下值的数组:
- 该表单的 当前 state,初始值为提供的 初始 state,当表单被提交后则改为传入的 action 的返回值。
- 传入
<form>
标签的action
属性的 新 action,或者手动在startTransition
中调用它。 - 一个 pending state,可以在处理 action 的过程中使用它。
表单被提交后,传入的 action 函数会被执行。返回值将会作为该表单的新的 当前 state。
传入的 action 接受到的第一个参数将会变为该表单的 当前 state。当表单第一次被提交时将会传入提供的 初始 state,之后都将传入上一次调用 action 函数的返回值。余下参数与未使用 useActionState
前接受的参数别无二致[1]。
function action(currentState, formData) {
// ...
return 'next state';
}
第 1 个示例 共 2 个示例: 展示表单错误
将 action 包裹进 useActionState
即可展示诸如错误信息或服务器函数返回的 toast 等信息。
import { useActionState, useState } from "react"; import { addToCart } from "./actions.js"; function AddToCartForm({itemID, itemTitle}) { const [message, formAction, isPending] = useActionState(addToCart, null); return ( <form action={formAction}> <h2>{itemTitle}</h2> <input type="hidden" name="itemID" value={itemID} /> <button type="submit">加入购物车</button> {isPending ? "加载中……" : message} </form> ); } export default function App() { return ( <> <AddToCartForm itemID="1" itemTitle="JavaScript:权威指南" /> <AddToCartForm itemID="2" itemTitle="JavaScript:优点荟萃" /> </> ) }