React Actions 与 useActionState
定义服务器端和客户端操作,处理表单提交,并跟踪待处理状态。
React Actions 与 useActionState 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
欢迎
在本课中,您将定义 React 19 Actions,使用 useActionState 管理表单提交状态,并妥善处理等待状态和错误状态。
什么是 React Actions?
Actions 是传递给表单 `action` 属性(或按钮 `formAction`)的异步函数。React 19 会对它们进行特殊处理:跟踪等待状态、处理错误,并自动与过渡集成。
Next.js 中的服务器操作
在使用 App Router 的 Next.js 中,只需在函数顶部添加 'use server',即可将其变为服务器操作。表单提交时,React 会在服务器上调用它,不需要 API 路由。
'use server';
export async function createPost(formData) {
const title = formData.get('title');
await db.insert(posts).values({ title });
revalidatePath('/posts');
}在表单中使用操作
将服务器操作或客户端操作直接传递给表单的 `action` 属性。表单提交时,React 会将 FormData 传递给它。
import { createPost } from './actions';
export default function NewPostForm() {
return (
<form action={createPost}>
<input name="title" />
<button type="submit">Create</button>
</form>
);
}useActionState
useActionState 会包装一个操作,为您提供当前状态(上一次操作的结果)和一个表示是否正在等待的布尔值。包装后的函数会传递给表单的 action。
'use client';
import { useActionState } from 'react';
import { createPost } from './actions';
function NewPostForm() {
const [state, action, isPending] = useActionState(createPost, null);
return (
<form action={action}>
{state?.error && <p>{state.error}</p>}
<input name="title" />
<button disabled={isPending}>Create</button>
</form>
);
}返回状态的操作
将操作与 useActionState 配合使用时,服务器操作会接收 `(prevState, formData)`。请返回一个包含成功或错误信息的对象,它会成为新的状态。
'use server';
export async function createPost(prevState, formData) {
const title = formData.get('title')?.toString();
if (!title) return { error: 'Title is required' };
await db.insert(posts).values({ title });
return { success: true };
}使用 isPending 禁用提交
使用 useActionState 返回的 isPending 值,在操作运行期间禁用提交按钮并显示加载指示器。
<button type="submit" disabled={isPending}>
{isPending ? 'Saving...' : 'Save'}
</button>客户端操作
操作不一定要在服务器端运行。客户端操作是不带 'use server' 的普通异步函数,但仍可通过 useActionState 获得等待状态和状态管理。
async function clientAction(prevState, formData) {
const res = await fetch('/api/post', {
method: 'POST', body: formData,
});
if (!res.ok) return { error: 'Failed' };
return { success: true };
}使用 useFormStatus 处理子组件
在深层嵌套的提交按钮中,使用 `useFormStatus()` 读取父表单的等待状态,无需逐层传递属性。
'use client';
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>Submit</button>;
}渐进式增强
React Actions 与服务器操作即使在没有 JavaScript 的情况下也能工作(渐进式增强)。浏览器会向 Next.js 处理程序提交原生表单 POST 请求,因此该功能在 JS 加载前也能正常使用。
快速检查
useActionState 返回什么,使您能够在表单操作运行期间显示加载状态?
回顾
React Actions 是传递给表单 action 的异步函数。useActionState 会包装一个操作,为您提供状态、包装后的操作函数和 isPending。服务器操作需要添加 'use server',并在服务器上运行。
接下来
下一课:**使用 useOptimistic 实现即时反馈**——您将展示服务器变更操作进行期间的乐观界面更新。
常见问题解答
「React Actions 与 useActionState」课时是免费的吗?
是的 — 「React Actions 与 useActionState」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「React Actions 与 useActionState」这节课中我会学到什么?
定义服务器端和客户端操作,处理表单提交,并跟踪待处理状态。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「React Actions 与 useActionState」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- React Server Components 详解
- 使用 use() 钩子读取异步资源
- React Actions 与 useActionState
- 使用 useOptimistic 实现即时反馈