Next.js 数据更新:服务器函数创建与调用教程
如何更新数据
在 Next.js 中,你可以使用 React 的服务器函数(Server Functions)来更新数据。 本页将介绍如何创建和调用服务器函数。
创建服务器函数
通过使用 use server
指令可以定义服务器函数。你可以将该指令放在一个异步函数的顶部来标记该函数为服务器函数,或者放在一个单独文件的顶部来标记该文件的所有导出内容。我们建议在大多数情况下使用单独的文件。
'use server'
export async function createPost(formData: FormData) {}
export async function deletePost(formData: FormData) {}
服务器组件
通过在函数体顶部添加 "use server"
指令,可以在服务器组件中内联服务器函数:
export default function Page() {
// 服务器操作
async function createPost() {
'use server'
// 更新数据
// ...
}
return <></>
}
客户端组件
在客户端组件中无法定义服务器函数。但是,可以通过从一个顶部有 "use server"
指令的文件中导入它们来调用服务器函数:
'use server'
export async function createPost() {}
'use client'
import { createPost } from '@/app/actions'
export function Button() {
return <button formAction={createPost}>创建</button>
}
调用服务器函数
调用服务器函数主要有两种方式:
- 服务器和客户端组件中的表单
- 客户端组件中的事件处理程序
表单
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>
)
}
'use server'
export async function createPost(formData: FormData) {
const title = formData.get('title')
const content = formData.get('content')
// 更新数据
// 重新验证缓存
}
小贴士:当传递给
action
属性时,服务器函数也被称为服务器操作。
事件处理程序
你可以在客户端组件中通过使用事件处理程序(如 onClick
)来调用服务器函数。
'use client'
import { incrementLike } from './actions'
import { useState } from 'react'
export default function LikeButton({ initialLikes }: { initialLikes: number }) {
const [likes, setLikes] = useState(initialLikes)
return (
<>
<p>总点赞数: {likes}</p>
<button
onClick={async () => {
const updatedLikes = await incrementLike()
setLikes(updatedLikes)
}}
>
点赞
</button>
</>
)
}
显示加载状态
在执行服务器函数时,可以使用 React 的 useActionState
钩子显示加载指示器。此钩子返回一个 pending
布尔值:
'use client'
import { useActionState } from 'react'
import { createPost } from '@/app/actions'
import { LoadingSpinner } from '@/app/ui/loading-spinner'
export function Button() {
const [state, action, pending] = useActionState(createPost, false)
return (
<button onClick={async () => action()}>
{pending ? <LoadingSpinner /> : '创建帖子'}
</button>
)
}
重新验证缓存
在执行更新后,可以通过在服务器函数中调用 revalidatePath
或 revalidateTag
来重新验证 Next.js 缓存并显示更新后的数据:
'use server'
import { revalidatePath } from 'next/cache'
export async function createPost(formData: FormData) {
// 更新数据
// ...
revalidatePath('/posts')
}
重定向
在执行更新后,你可能需要将用户重定向到不同的页面。可以在服务器函数中调用 redirect
来实现:
'use server'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
// 更新数据
// ...
redirect('/posts')
}
API 参考
阅读 API 参考 ,了解有关本页中提到的功能的更多信息。
- revalidatePath
revalidatePath 函数的 API 参考。
- revalidateTag
revalidateTag 函数的 API 参考。
- 重定向
重定向函数的 API 参考。
更多建议: