Перейти к содержимому

5. Actions: мутации данных

action — серверная функция для обработки мутаций: создания, обновления, удаления данных. Вызывается при отправке формы через <Form method="post">.

import { json, redirect } from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";
export async function action({ request }) {
const formData = await request.formData();
const name = formData.get("name") as string;
const email = formData.get("email") as string;
// Валидация
if (!name || name.length < 2) {
return json({ error: "Имя слишком короткое" }, { status: 400 });
}
// Сохранение
await db.user.create({ data: { name, email } });
// Редирект после успеха
return redirect("/users");
}
export default function NewUser() {
const actionData = useActionData<typeof action>();
return (
<Form method="post">
<input name="name" placeholder="Имя" />
<input name="email" placeholder="Email" />
{actionData?.error && <p>{actionData.error}</p>}
<button type="submit">Создать</button>
</Form>
);
}
export async function action({ request }) {
const formData = await request.formData();
const intent = formData.get("intent");
switch (intent) {
case "create":
return createUser(formData);
case "delete":
return deleteUser(formData.get("id") as string);
case "update":
return updateUser(formData);
default:
return json({ error: "Неизвестное действие" }, { status: 400 });
}
}
// В компоненте:
<Form method="post">
<button name="intent" value="create">Создать</button>
</Form>
<Form method="post">
<input type="hidden" name="id" value={user.id} />
<button name="intent" value="delete">Удалить</button>
</Form>
import { z } from "zod";
import { parseWithZod } from "@conform-to/zod";
const schema = z.object({
email: z.string().email("Неверный email"),
password: z.string().min(8, "Минимум 8 символов"),
});
export async function action({ request }) {
const formData = await request.formData();
const submission = parseWithZod(formData, { schema });
if (submission.status !== "success") {
return json(submission.reply());
}
// Данные валидны
const { email, password } = submission.value;
await createUser({ email, password });
return redirect("/dashboard");
}
import { useSubmit } from "@remix-run/react";
export default function AutoSave() {
const submit = useSubmit();
function handleChange(event) {
submit(event.currentTarget, {
method: "post",
debounce: 500, // через 500ms после последнего изменения
});
}
return (
<Form method="post" onChange={handleChange}>
<textarea name="content" />
</Form>
);
}