Skip to main content
Практика завдань

Дії сервера в Next.js

Дії на сервері — це асинхронні функції, які виконуються на сервері. Вони дозволяють змінювати дані (створювати, оновлювати, видаляти) безпосередньо з компонентів, не створюючи окремі API кінцеві точки.

Як визначити Дію на сервері

Дія на сервері — це функція, позначена директивою 'use server':

tsx
// actions/problem.ts 'use server' import { db } from '@/lib/db' import { revalidatePath } from 'next/cache' export async function solveProblem(problemId: string, userId: string) { await db.user.update({ where: { id: userId }, data: { solvedProblems: { push: problemId } } }) revalidatePath('/problems') }

Директиву можна встановити на рівні файлу (як вище) або на рівні окремої функції:

tsx
export default async function Page() { async function handleSubmit(formData: FormData) { 'use server' const name = formData.get('name') await db.user.update({ where: { id: userId }, data: { name } }) } return <form action={handleSubmit}>...</form> }

Використання з формами

Дії на сервері можна передавати безпосередньо в action форми. Форма працює навіть без JavaScript на стороні клієнта (прогресивне покращення):

tsx
// app/settings/page.tsx import { db } from '@/lib/db' import { revalidatePath } from 'next/cache' export default async function SettingsPage() { async function updateProfile(formData: FormData) { 'use server' const name = formData.get('name') as string await db.user.update({ where: { id: currentUserId }, data: { name } }) revalidatePath('/settings') } return ( <form action={updateProfile}> <input name="name" placeholder="Ім'я на IT Lead" /> <button type="submit">Зберегти</button> </form> ) }

Використання з useTransition

Для оптимістичних оновлень і вказівки завантаження:

tsx
'use client' import { useTransition } from 'react' import { solveProblem } from '@/actions/problem' export function SolveButton({ problemId, userId }: { problemId: string userId: string }) { const [isPending, startTransition] = useTransition() return ( <button disabled={isPending} onClick={() => { startTransition(() => solveProblem(problemId, userId)) }} > {isPending ? 'Перевірка...' : 'Вирішено'} </button> ) }

Валідація даних

Дії на сервері отримують введення користувача, тому валідація є обов'язковою:

tsx
'use server' import { z } from 'zod' const schema = z.object({ name: z.string().min(2).max(50), email: z.string().email() }) export async function updateUser(formData: FormData) { const result = schema.safeParse({ name: formData.get('name'), email: formData.get('email') }) if (!result.success) { return { error: result.error.flatten().fieldErrors } } await db.user.update({ where: { id: currentUserId }, data: result.data }) revalidatePath('/settings') return { success: true } }

Повторна валідація після зміни

Після зміни даних потрібно оновити кеш:

tsx
'use server' import { revalidatePath, revalidateTag } from 'next/cache' import { redirect } from 'next/navigation' export async function createProblem(data: ProblemData) { await db.problem.create({ data }) revalidateTag('problems') // інвалідовує кеш даних за тегом revalidatePath('/problems') // інвалідовує кеш повного маршруту redirect('/problems') // перенаправляє після створення }

Порада для інтерв'ю:

Дії на сервері не є заміною REST API. Вони призначені для мутацій даних з UI. Для публічних API, інтеграцій з іншими сервісами або вебхуками використовуйте обробники маршрутів.

Корисні ресурси

Суміжні теми

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань