Skip to content

更新数据

¥Updating Data

你可以使用 React 的 服务器函数 更新 Next.js 中的数据。本页将介绍如何使用 createinvoke 服务器功能。

¥You can update data in Next.js using React's Server Functions. This page will go through how you can create and invoke Server Functions.

创建服务器函数

¥Creating Server Functions

可以使用 use server 指令定义服务器函数。你可以将指令放在异步函数的顶部以将该函数标记为服务器函数,或者放在单独文件的顶部以标记该文件的所有导出。我们建议在大多数情况下使用单独的文件。

¥A Server Function can be defined by using the use server directive. You can place the directive at the top of an asynchronous function to mark the function as a Server Function, or at the top of a separate file to mark all exports of that file. We recommend using a separate file in most instances.

ts
'use server'

export async function createPost(formData: FormData) {}

export async function deletePost(formData: FormData) {}
js
'use server'

export async function createPost(formData) {}

export async function deletePost(formData) {}

服务器组件

¥Server Components

可以通过将 "use server" 指令添加到函数主体顶部,在服务器组件中内联服务器函数:

¥Server Functions can be inlined in Server Components by adding the "use server" directive to the top of the function body:

tsx
export default function Page() {
  // Server Action
  async function createPost() {
    'use server'
    // Update data
    // ...

  return <></>
}
jsx
export default function Page() {
  // Server Action
  async function createPost() {
    'use server'
    // Update data
    // ...
  }

  return <></>
}

客户端组件

¥Client Components

无法在客户端组件中定义服务器函数。但是,你可以通过从顶部包含 "use server" 指令的文件中导入它们来在客户端组件中调用它们:

¥It's not possible to define Server Functions in Client Components. However, you can invoke them in Client Components by importing them from a file that has the "use server" directive at the top of it:

ts
'use server'

export async function createPost() {}
js
'use server'

export async function createPost() {}
tsx
'use client'

import { createPost } from '@/app/actions'

export function Button() {
  return <button formAction={createPost}>Create</button>
}
jsx
'use client'

import { createPost } from '@/app/actions'

export function Button() {
  return <button formAction={createPost}>Create</button>
}

调用服务器函数

¥Invoking Server Functions

有两种主要方式可以调用服务器函数:

¥There are two main ways you can invoke a Server Function:

  1. 服务器和客户端组件中的 表单

    ¥Forms in Server and Client Components

  2. 客户端组件中的 事件处理程序

    ¥Event Handlers in Client Components

表单

¥Forms

React 扩展了 HTML <form> 元素,允许使用 HTML action 属性调用服务器函数。

¥React extends the HTML <form> element to allow Server Function to be invoked with the HTML action prop.

在表单中调用时,该函数会自动接收 FormData 对象。你可以使用原生 FormData 方法 提取数据:

¥When invoked in a form, the function automatically receives the FormData object. You can extract the data using the native FormData methods:

tsx
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>
  )
}
jsx
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>
  )
}
ts
'use server'

export async function createPost(formData: FormData) {
  const title = formData.get('title')
  const content = formData.get('content')

  // Update data
  // Revalidate cache
}
js
'use server'

export async function createPost(formData) {
  const title = formData.get('title')
  const content = formData.get('content')

  // Update data
  // Revalidate cache
}

需要了解:当传递给 action prop 时,服务器函数也称为服务器操作。

¥Good to know: When passed to the action prop, Server Functions are also known as Server Actions.

事件处理程序

¥Event Handlers

你可以使用事件处理程序(例如 onClick)在客户端组件中调用服务器函数。

¥You can invoke a Server Function in a Client Component by using event handlers such as onClick.

tsx
'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>
    </>
  )
}
jsx
'use client'

import { incrementLike } from './actions'
import { useState } from 'react'

export default function LikeButton({ initialLikes }) {
  const [likes, setLikes] = useState(initialLikes)

  return (
    <>
      <p>Total Likes: {likes}</p>
      <button
        onClick={async () => {
          const updatedLikes = await incrementLike()
          setLikes(updatedLikes)
        }}
      >
        Like
      </button>
    </>
  )
}

显示待处理状态

¥Showing a pending state

在执行服务器函数时,你可以使用 React 的 useActionState 钩子显示加载指示器。此钩子返回 pending 布尔值:

¥While executing a Server Function, you can show a loading indicator with React's useActionState hook. This hook returns a pending boolean:

tsx
'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>
  )
}
jsx
'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>
  )
}

重新验证缓存

¥Revalidating the cache

执行更新后,你可以通过在服务器函数中调用 revalidatePathrevalidateTag 来重新验证 Next.js 缓存并显示更新的数据:

¥After performing an update, you can revalidate the Next.js cache and show the updated data by calling revalidatePath or revalidateTag within the Server Function:

ts
'use server'

import { revalidatePath } from 'next/cache'

export async function createPost(formData: FormData) {
  // Update data
  // ...

  revalidatePath('/posts')
}
js
'use server'

import { revalidatePath } from 'next/cache'

export async function createPost(formData) {
  // Update data
  // ...
  revalidatePath('/posts')
}

重定向

¥Redirecting

你可能希望在执行更新后将用户重定向到其他页面。你可以通过在服务器函数中调用 redirect 来执行此操作:

¥You may want to redirect the user to a different page after performing an update. You can do this by calling redirect within the Server Function:

ts
'use server'

import { redirect } from 'next/navigation'

export async function createPost(formData: FormData) {
  // Update data
  // ...

  redirect('/posts')
}
js
'use server'

import { redirect } from 'next/navigation'

export async function createPost(formData) {
  // Update data
  // ...

  redirect('/posts')
}

Next.js v15.2 中文网 - 粤ICP备13048890号