react server action示例
React Server Action(简称SA)是React 18+推出的核心特性,它允许你直接在客户端触发服务器端的异步逻辑,无需手动写API请求(如fetch/axios),React会自动处理客户端与服务端的通信、数据序列化/反序列化。下面从核心互联方式、具体示例、关键细节三个维度讲清楚两者的互联逻辑。
一、前置条件
使用Server Action前需满足:
- React版本 ≥ 18(推荐19+)
- 开启Server Components(SC)环境(Next.js 14+ App Router默认开启,纯React需配置框架如Remix/Redwood)
- Server Action必须用
'use server'指令标记(标识这是运行在服务端的函数)
二、核心互联逻辑(客户端 ↔ 服务端)
Server Action与客户端的互联核心是「客户端触发 → 服务端执行 → 结果返回客户端」,主要有两种触发方式(表单集成、手动触发),下面用Next.js 14+(最主流场景)举例。
方式1:表单集成(最原生/推荐)
这是React官方推荐的方式,表单的action属性直接指向Server Action,React会自动处理:
- 客户端提交表单时,自动收集
FormData并传递给Server Action - 自动处理加载状态、提交防抖、页面跳转(可选)
- 自动返回执行结果/错误到客户端
完整示例(Next.js App Router):
// 1. 定义Server Action(可写在Server Component文件,或单独的actions.ts)
// app/actions.ts(服务端文件,顶部标记'use server')
'use server'
import { revalidatePath } from 'next/cache'
// 定义Server Action:接收客户端传递的FormData,执行服务端逻辑(如操作数据库)
export async function submitUserInfo(formData: FormData) {
// 从FormData中提取客户端传递的数据
const name = formData.get('name') as string
const age = Number(formData.get('age'))
// 服务端逻辑:验证、操作数据库、调用第三方API等(仅运行在服务端)
if (!name || age < 0) {
throw new Error('姓名不能为空,年龄必须为正数') // 抛错会自动返回客户端
}
// 模拟数据库操作
console.log('服务端接收数据:', { name, age }) // 仅在服务端控制台打印
// 重新验证页面缓存(可选,更新数据后刷新页面数据)
revalidatePath('/')
// 返回结果给客户端
return { success: true, message: `用户${name}信息提交成功` }
}
// 2. 客户端组件(触发Server Action)
// app/page.tsx(客户端组件,用'use client'标记)
'use client'
import { useFormStatus } from 'react-dom'
import { submitUserInfo } from './actions'
// 辅助组件:展示提交状态(加载/成功/失败)
function SubmitButton() {
const { pending } = useFormStatus() // 获取表单提交状态(React内置)
return (
<button type="submit" disabled={pending}>
{pending ? '提交中...' : '提交信息'}
</button>
)
}
// 客户端组件:渲染表单,action指向Server Action
export default function UserForm() {
// 捕获Server Action的执行结果/错误
const [submitError, setSubmitError] = useState<string | null>(null)
const [submitResult, setSubmitResult] = useState<{ success: boolean; message: string } | null>(null)
// 包装Server Action,处理返回结果/错误
const handleSubmit = async (formData: FormData) => {
setSubmitError(null)
setSubmitResult(null)
try {
// 触发Server Action,等待返回结果
const result = await submitUserInfo(formData)
setSubmitResult(result)
} catch (err) {
// 捕获服务端抛出的错误
setSubmitError((err as Error).message)
}
}
return (
<div>
{/* 表单action指向包装后的处理函数(或直接指向submitUserInfo) */}
<form action={handleSubmit}>
<div>
<label>姓名:</label>
<input type="text" name="name" required />
</div>
<div>
<label>年龄:</label>
<input type="number" name="age" min="0" required />
</div>
<SubmitButton />
</form>
{/* 展示结果/错误 */}
{submitError && <p style={{ color: 'red' }}>{submitError}</p>}
{submitResult && <p style={{ color: 'green' }}>{submitResult.message}</p>}
</div>
)
}
方式2:手动触发(非表单场景)
如果不是表单提交(比如按钮点击、定时器触发),可以用useActionState Hook手动触发Server Action,实现更灵活的交互。
完整示例:
// 1. 还是用上面的submitUserInfo Server Action
// 2. 客户端组件(手动触发)
'use client'
import { useActionState } from 'react'
import { submitUserInfo } from './actions'
// 初始化状态
const initialState = { success: false, message: '', error: '' }
export default function ManualTrigger() {
// useActionState:绑定Server Action + 初始化状态,返回[状态, 触发函数]
const [state, dispatch] = useActionState(submitUserInfo, initialState)
// 手动构造FormData并触发Server Action
const handleClick = () => {
const formData = new FormData()
formData.append('name', '张三')
formData.append('age', '25')
dispatch(formData) // 触发Server Action
}
return (
<div>
<button onClick={handleClick} disabled={state.loading}>
手动提交
</button>
{state.error && <p style={{ color: 'red' }}>{state.error}</p>}
{state.success && <p style={{ color: 'green' }}>{state.message}</p>}
</div>
)
}
三、关键互联细节
-
数据传递规则
- 客户端 → 服务端:支持
FormData(推荐)、JSON可序列化数据(对象/数组/字符串/数字,React自动序列化);不支持函数、DOM元素等不可序列化数据。 - 服务端 → 客户端:返回值需是JSON可序列化数据(对象/数组/基本类型),抛错会被客户端捕获(需用try/catch)。
- 客户端 → 服务端:支持
-
状态同步
- 服务端修改数据后,用
revalidatePath/revalidateTag刷新客户端缓存,保证页面数据最新。 - 客户端用
useFormStatus(表单场景)、useActionState(手动场景)获取加载/成功/失败状态。
- 服务端修改数据后,用
-
跨组件调用
- Server Action可导出到任意客户端组件,无需担心跨文件调用(React自动处理通信)。
- 注意:Server Action不能直接在客户端组件的渲染阶段调用(只能在事件处理函数中触发)。
总结
React Server Action与客户端的互联核心要点:
- 触发方式:优先用表单
action属性(原生集成),非表单场景用useActionState手动触发。 - 数据传递:客户端通过
FormData/可序列化数据传参,服务端返回可序列化结果,React自动处理通信。 - 状态/错误:用
useFormStatus/useActionState管理提交状态,try/catch捕获服务端错误,revalidatePath同步页面数据。
这种方式无需手动写API层,大幅简化了客户端与服务端的互联逻辑,是React生态下前后端交互的主流方案。

浙公网安备 33010602011771号