Server Function تابعی غیرهمزمان است که روی سرور اجرا میشود و از کلاینت قابل فراخوانی است. در زمینهٔ تغییر داده، به آن Server Action نیز گفته میشود. این توابع با معماری کش Next.js یکپارچه هستند و فقط از طریق متد POST قابل اجرا هستند.
برای تعریف، از دستور 'use server' استفاده کنید. میتوان آن را درون تابع یا بالای فایل قرار داد:
// app/lib/actions.ts
export async function createPost(formData: FormData) {
'use server'
const title = formData.get('title')
const content = formData.get('content')
// بهروزرسانی داده و بازسازی کش
}میتوان Server Function را بهصورت داخلی در کامپوننت سروری تعریف کرد:
// app/page.tsx
export default function Page() {
async function createPost(formData: FormData) {
'use server'
// ...
}
return <></>
}کامپوننتهای کلاینتی نمیتوانند Server Function تعریف کنند، اما میتوانند آن را import و فراخوانی کنند:
// app/ui/button.tsx
'use client'
import { createPost } from '@/app/actions'
export function Button() {
return <button formAction={createPost}>Create</button>
}// app/client-component.tsx
'use client'
export default function ClientComponent({ updateItemAction }) {
return <form action={updateItemAction}>...</form>
}action یا formActiononClick یا useEffect// app/ui/form.tsx
import { createPost } from '@/app/actions'
export function Form() {
return (
<form action={createPost}>
<input name="title" />
<input name="content" />
<button>Create</button>
</form>
)
}// app/like-button.tsx
'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>
</>
)
}برای نمایش وضعیت pending، از هوک useActionState استفاده کنید:
// app/ui/button.tsx
'use client'
import { useActionState, startTransition } 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={() => startTransition(action)}>
{pending ? <LoadingSpinner /> : 'Create Post'}
</button>
)
}برای تازهسازی دادهها، از revalidatePath یا revalidateTag استفاده کنید:
// app/lib/actions.ts
import { revalidatePath } from 'next/cache'
export async function createPost(formData) {
'use server'
// بهروزرسانی داده
revalidatePath('/posts')
}برای هدایت کاربر پس از تغییر داده، از redirect استفاده کنید:
// app/lib/actions.ts
'use server'
import { revalidatePath } from 'next/cache'
import { redirect } from 'next/navigation'
export async function createPost(formData) {
revalidatePath('/posts')
redirect('/posts')
}در Server Action میتوان کوکیها را با API cookies() دریافت، تنظیم یا حذف کرد:
// app/actions.ts
'use server'
import { cookies } from 'next/headers'
export async function exampleAction() {
const cookieStore = await cookies()
cookieStore.set('name', 'Delba')
cookieStore.delete('name')
}برای فراخوانی خودکار هنگام mount یا تغییر وابستگیها:
// app/view-count.tsx
'use client'
import { incrementViews } from './actions'
import { useState, useEffect, useTransition } from 'react'
export default function ViewCount({ initialViews }) {
const [views, setViews] = useState(initialViews)
const [isPending, startTransition] = useTransition()
useEffect(() => {
startTransition(async () => {
const updatedViews = await incrementViews()
setViews(updatedViews)
})
}, [])
return <p>Total Views: {views}</p>
}با استفاده از Server Functions در Next.js میتوان دادهها را بهروزرسانی کرد، کش را بازسازی نمود، و رابط کاربری را همزمان تازه کرد. این توابع از طریق فرمها، دکمهها یا هوکها فراخوانی میشوند و تجربهای سریع و تعاملی برای کاربر فراهم میسازند.