Next.js: 如何更新数据
目录
您可以使用 React 的服务器函数在 Next.js 中更新数据。本文将介绍如何创建和调用 Server Functions。
创建服务器函数 #
可以使用 use server 来定义 Server Function 命令。您可以将该指令放在异步函数的顶部,以将该函数标记为服务器函数,或者放在单独文件的顶部,以标记该文件的所有导出。我们建议在大多数情况下使用单独的文件。
'use server'
export async function createPost(formData: FormData) {}
export async function deletePost(formData: FormData) {}
服务器组件 #
通过在函数体的顶部添加 “use server” 指令,可以在 Server Components 中内联服务器函数:
export default function Page() {
// Server Action
async function createPost() {
'use server'
// Update data
// ...
return <></>
}
客户端组件 #
无法在 Client Components 中定义 Server Functions。但是,您可以在 Client Components 中调用它们,方法是从顶部带有 “use server” 指令的文件中导入它们:
'use server'
export async function createPost() {}
'use client'
import { createPost } from '@/app/actions'
export function Button() {
return <button formAction={createPost}>Create</button>
}
调用 Server 函数 #
调用服务器函数的主要方法有两种:
表单 #
React 扩展了 HTML 表单元素以允许使用 HTML action 属性调用 Server Function。
在表单中调用时,该函数会自动接收 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">Create</button>
</form>
)
}
'use server'
export async function createPost(formData: FormData) {
const title = formData.get('title')
const content = formData.get('content')
// Update data
// Revalidate cache
}
事件处理程序 #
您可以使用事件处理程序(如 onClick)在 Client Component 中调用 Server Function。
'use client'
import { incrementLike } from './actions'
import { useState } from 'react'
export default function LikeButton({ initialLikes }: { initialLikes: number }) {
const [likes, setLikes] = useState(initialLikes)
return (
<>
<p>Total Likes: {likes}</p>
<button
onClick={async () => {
const updatedLikes = await incrementLike()
setLikes(updatedLikes)
}}
>
Like
</button>
</>
)
}
显示待处理状态 #
在执行服务器函数时,你可以使用 React 的 useActionState 显示加载指示器 钩。此钩子返回一个待处理的布尔值:
'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 /> : 'Create Post'}
</button>
)
}
重新验证缓存 #
执行更新后,您可以通过在 Server Function 中调用 revalidatePath 或 revalidateTag 来重新验证 Next.js 缓存并显示更新的数据:
'use server'
import { revalidatePath } from 'next/cache'
export async function createPost(formData: FormData) {
// Update data
// ...
revalidatePath('/posts')
}
重定向 #
您可能希望在执行更新后将用户重定向到其他页面。您可以通过在 Server Function 中调用 redirect 来执行此作:
'use server'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
// Update data
// ...
redirect('/posts')
}