Серверные действия: Server Actions

Меняем данные на сервере, вызывая серверную функцию прямо из формы — без написания API-эндпоинта.

Server Action — асинхронная функция с директивой 'use server', которая выполняется только на сервере, но вызывается из клиента как обычная функция; идеальна для отправки форм и мутаций данных.

Зачем они нужны

Раньше, чтобы сохранить форму, нужно было: создать API-эндпоинт, написать fetch на клиенте, обработать ответ. Server Actions убирают эту прослойку: вы пишете серверную функцию и привязываете её прямо к форме.

Действие в форме

Объявляем функцию с 'use server' и передаём её в проп action формы. Браузер отправит данные формы, а функция выполнится на сервере:

// app/new/page.tsx — серверный компонент
import { db } from "@/lib/db";

export default function NewPostPage() {
  async function createPost(formData) {
    "use server";
    const title = formData.get("title");
    await db.posts.create({ data: { title } });
  }

  return (
    <form action={createPost}>
      <input name="title" />
      <button type="submit">Создать</button>
    </form>
  );
}

Обратите внимание: никакого onSubmit, fetch или эндпоинта. Данные формы приходят как formData прямо на сервер.

Чем это безопасно

Код действия живёт на сервере: в браузер уходит только ссылка-идентификатор, а не сама логика. Поэтому в Server Action можно безопасно обращаться к БД и использовать секреты — они не утекают клиенту.

Прогрессивное улучшение

Поскольку действие привязано к <form>, форма работает даже до загрузки JavaScript — браузер отправит её штатно. Это называется прогрессивным улучшением. Смоделируем разбор formData на чистом JS:

// имитация FormData как массива пар [имя, значение]
const entries = [["title", "Привет"], ["tag", "next"], ["tag", "react"]];
const form = new Map();
for (const [k, v] of entries) {
  if (form.has(k)) form.set(k, [].concat(form.get(k), v));
  else form.set(k, v);
}
console.log("title:", form.get("title"));
console.log("tags:", form.get("tag"));

Вывод:

title: Привет
tags: [ 'next', 'react' ]

Итог

  • Server Action — серверная функция с 'use server', вызывается прямо из формы.
  • Не нужен отдельный API-эндпоинт и ручной fetch для мутаций.
  • Логика и секреты остаются на сервере; форма работает даже без JS.
Проверьте себя
1. Что помечает директива 'use server' внутри функции?
AЧто функция выполнится только на сервере (Server Action)
BЧто компонент станет клиентским
CЧто нужно кэшировать результат
DЧто функция — это React-хук
2. Какое главное удобство дают Server Actions?
AОни ускоряют CSS
BПозволяют менять данные без отдельного API-эндпоинта и ручного fetch
CЗаменяют useState
DОтключают серверный рендеринг
3. Как Server Action получает данные отправленной формы?
AЧерез пропсы компонента
BЧерез аргумент formData (объект FormData)
CЧерез window.location
DЧерез useState
Поддержать проект