В React Router начиная с версии 6.4 появилась возможность работать с
формами не только через обычные HTML-элементы <form>
с событиями onSubmit, но и программно, используя хук
useSubmit. Этот подход позволяет выполнять навигацию и
отправку данных без прямого участия пользователя, сохраняя преимущества
маршрутизации и загрузки данных через маршруты.
useSubmitХук useSubmit импортируется из пакета
react-router-dom:
import { useSubmit } from "react-router-dom";
Он возвращает функцию, которая позволяет отправлять данные на текущий
маршрут или на другой маршрут без использования стандартного
<form>.
Сигнатура функции submit:
submit(
target: HTMLFormElement | FormData | URLSearchParams | Object,
options?: {
method?: "get" | "post" | "put" | "patch" | "delete";
action?: string;
encType?: string;
replace?: boolean;
}
)
<form>, объект FormData,
URLSearchParams или обычный объект."post".enctype в HTML.true, история навигации
заменяется вместо добавления новой записи.<form>Самый простой способ — передать в submit ссылку на
форму:
import { useSubmit } from "react-router-dom";
function ContactForm() {
const submit = useSubmit();
const handleClick = () => {
const form = document.getElementById("contact-form");
submit(form);
};
return (
<form id="contact-form">
<input name="name" />
<input name="email" />
<button type="button" onCl ick={handleClick}>
Отправить
</button>
</form>
);
}
В этом примере форма не отправляется стандартным способом, а
программно через submit(form). React Router обработает
данные так же, как если бы форма была отправлена через
<Form method="post">.
Иногда нет необходимости использовать реальный
<form> на странице. Можно собрать данные в объекте
или FormData и отправить их напрямую:
function NewsletterSignup() {
const submit = useSubmit();
const handleSignup = () => {
const data = { email: "user@example.com" };
submit(data, { method: "post", action: "/signup" });
};
return (
<button onCl ick={handleSignup}>Подписаться</button>
);
}
Особенности:
{ key: value } React Router
автоматически преобразует его в FormData.get или post для
соответствия логике маршрута.action)useSubmit тесно интегрирован с системой
action в маршрутах React Router. Отправка данных через
submit вызовет соответствующий обработчик:
// В маршруте
{
path: "/signup",
element: <NewsletterSignup />,
action: async ({ request }) => {
const formData = await request.formData();
const email = formData.get("email");
await apiSubscribe(email);
return { success: true };
}
}
Таким образом, отправка через submit полностью
поддерживает серверную или клиентскую обработку данных маршрута.
multipart/form-data.const formData = new FormData();
formData.append("file", fileInput.files[0]);
submit(formData, { method: "post", encType: "multipart/form-data" });
<form> для динамических
интерфейсов:const data = { search: query };
submit(data, { method: "get", action: "/search" });
if (window.confirm("Вы уверены?")) {
submit(formElement);
}
FormData с
replace для обновления контента:const fd = new FormData();
fd.append("avatar", file);
submit(fd, { method: "post", encType: "multipart/form-data", replace: true });
useSubmitaction и навигация работают автоматически.FormData с файлами.replace.useSubmit предоставляет мощный инструмент для управления
формами в React Router, объединяя преимущества SPA и привычной работы с
формами HTML. Он позволяет создавать динамичные интерфейсы с гибким
контролем отправки данных и интеграцией с маршрутизатором.