Формы, ревалидация и обновление данных

Закрываем цикл: отправили форму на сервер — и сразу видим свежие данные на странице.

После мутации через Server Action кэш нужно сбросить функциями revalidatePath или revalidateTag, иначе пользователь увидит старые данные из кэша.

Проблема устаревших данных

Next.js агрессивно кэширует. Если вы добавили запись через Server Action, но не сказали фреймворку «данные изменились», страница со списком может показать прежнее содержимое. Решение — ревалидация после мутации.

// app/todos/actions.ts
"use server";
import { revalidatePath } from "next/cache";
import { db } from "@/lib/db";

export async function addTodo(formData) {
  const text = formData.get("text");
  await db.todos.create({ data: { text } });
  revalidatePath("/todos"); // сбросить кэш страницы списка
}

После revalidatePath("/todos") Next.js перерисует список с учётом новой записи.

Два инструмента ревалидации

ФункцияЧто сбрасывает
revalidatePath("/todos")Кэш конкретного маршрута
revalidateTag("todos")Все запросы, помеченные тегом todos

Теги удобны, когда одни и те же данные используются на нескольких страницах: пометили fetch тегом — и одним вызовом обновили их везде.

Состояние отправки формы

Чтобы заблокировать кнопку на время отправки, в клиентском компоненте используют хук useFormStatus:

"use client";
import { useFormStatus } from "react-dom";

export default function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? "Сохраняем…" : "Сохранить"}
    </button>
  );
}

Полный цикл

Соберём логику воедино на простой модели «состояние списка после действия»:

let todos = ["купить хлеб"];

function addTodo(text) {
  todos = [...todos, text];   // мутация на «сервере»
  return "revalidate:/todos"; // сигнал обновить страницу
}

console.log(addTodo("позвонить маме"));
console.log("Список теперь:", todos);

Вывод:

revalidate:/todos
Список теперь: [ 'купить хлеб', 'позвонить маме' ]

Итог

  • После мутации вызывайте revalidatePath или revalidateTag, иначе данные останутся старыми.
  • Теги удобны, когда одни данные нужны на нескольких страницах.
  • useFormStatus даёт состояние pending для блокировки кнопки отправки.
Проверьте себя
1. Зачем после Server Action вызывать revalidatePath?
AЧтобы отправить форму
BЧтобы сбросить кэш и показать обновлённые данные
CЧтобы перейти на другую страницу
DЧтобы залогировать запрос
2. Когда удобнее использовать revalidateTag вместо revalidatePath?
AКогда одни и те же данные используются на нескольких страницах
BКогда нужно обновить CSS
CКогда форма клиентская
DНикогда — это одно и то же
3. Что даёт хук useFormStatus?
AТекст ошибки формы
BФлаг pending — идёт ли отправка формы прямо сейчас
CСписок полей формы
DURL текущей страницы
Поддержать проект