如何更新数据
您可以使用 React 的 服务端函数 (Server Functions) 在 Next.js 中更新数据。本页将介绍如何创建和调用服务端函数。
服务端函数
服务端函数是在服务器端执行的异步函数。由于它们是通过客户端发起的网络请求调用的,因此本质上是异步的。当作为 action
的一部分被调用时,它们也被称为服务端操作 (Server Actions)。
按照约定,action
是传递给 startTransition
的异步函数。服务端函数在以下情况下会自动被 startTransition
包裹:
- 通过
action
属性传递给<form>
- 通过
formAction
属性传递给<button>
- 传递给
useActionState
创建服务端函数
可以通过使用 use server
指令来定义服务端函数。您可以将该指令放在异步函数的顶部以将其标记为服务端函数,或者放在单独文件的顶部以标记该文件的所有导出。
export async function createPost(formData: FormData) {
'use server'
const title = formData.get('title')
const content = formData.get('content')
// 更新数据
// 重新验证缓存
}
export async function deletePost(formData: FormData) {
'use server'
const id = formData.get('id')
// 更新数据
// 重新验证缓存
}
export async function createPost(formData) {
'use server'
const title = formData.get('title')
const content = formData.get('content')
// 更新数据
// 重新验证缓存
}
export async function deletePost(formData) {
'use server'
const id = formData.get('id')
// 更新数据
// 重新验证缓存
}
服务端组件
可以通过在函数体顶部添加 "use server"
指令,在服务端组件中内联定义服务端函数:
export default function Page() {
// 服务端操作
async function createPost(formData: FormData) {
'use server'
// ...
}
return <></>
}
export default function Page() {
// 服务端操作
async function createPost(formData) {
'use server'
// ...
}
return <></>
}
客户端组件
无法在客户端组件中定义服务端函数。但您可以通过从顶部带有 "use server"
指令的文件导入它们,在客户端组件中调用这些函数:
'use server'
export async function createPost() {}
'use server'
export async function createPost() {}
调用服务端函数
有两种主要方式可以调用服务端函数:
表单
React 扩展了 HTML <form>
元素,允许通过 HTML action
属性调用服务端函数。
在表单中调用时,函数会自动接收 FormData
对象。您可以使用原生 FormData
方法提取数据:
import { createPost } from '@/app/actions'
export function Form() {
return (
<form action={createPost}>
<input type="text" name="title" />
<input type="text" name="content" />
<button type="submit">创建</button>
</form>
)
}
import { createPost } from '@/app/actions'
export function Form() {
return (
<form action={createPost}>
<input type="text" name="title" />
<input type="text" name="content" />
<button type="submit">创建</button>
</form>
)
}
'use server'
export async function createPost(formData: FormData) {
const title = formData.get('title')
const content = formData.get('content')
// 更新数据
// 重新验证缓存
}
'use server'
export async function createPost(formData) {
const title = formData.get('title')
const content = formData.get('content')
// 更新数据
// 重新验证缓存
}
须知: 当传递给
action
属性时,服务端函数也被称为_服务端操作 (Server Actions)_。
事件处理程序
您可以在客户端组件中使用 onClick
等事件处理程序调用服务端函数。
示例
显示等待状态
在执行服务端函数时,您可以使用 React 的 useActionState
钩子显示加载指示器。该钩子会返回一个 pending
布尔值:
重新验证缓存
执行更新后,您可以通过在服务端函数中调用 revalidatePath
或 revalidateTag
来重新验证 Next.js 缓存并显示更新后的数据:
import { revalidatePath } from 'next/cache'
export async function createPost(formData: FormData) {
'use server'
// 更新数据
// ...
revalidatePath('/posts')
}
import { revalidatePath } from 'next/cache'
export async function createPost(formData) {
'use server'
// 更新数据
// ...
revalidatePath('/posts')
}
重定向
您可能希望在执行更新后将用户重定向到其他页面。可以通过在服务端函数中调用 redirect
来实现:
'use server'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
// 更新数据
// ...
redirect('/posts')
}
'use server'
import { redirect } from 'next/navigation'
export async function createPost(formData) {
// 更新数据
// ...
redirect('/posts')
}