useFetcher — это хук библиотеки React Router,
предназначенный для выполнения фоновых операций, таких как отправка форм
или загрузка данных без необходимости навигации между страницами. Он
позволяет отделить процесс получения и отправки данных от маршрутизации,
обеспечивая асинхронное взаимодействие с сервером и более чистую
архитектуру приложения.
useFetcher создаёт объект, через который можно выполнять
различные операции:
import { useFetcher } from "react-router-dom";
function MyComponent() {
const fetcher = useFetcher();
return (
<fetcher.Form method="post" action="/submit">
<input name="name" />
<button type="submit">Отправить</button>
</fetcher.Form>
);
}
fetcher.Form — компонент формы,
который отправляет данные асинхронно, не вызывая полноценную
навигацию.method и action — аналог
стандартных атрибутов HTML-форм, определяющие HTTP-метод и путь для
отправки запроса.useFetcher возвращает объект с рядом ключевых свойств и
методов:
data — результат последнего
успешного запроса, можно использовать для отображения полученной
информации.
state — состояние запроса.
Возможные значения:
"idle" — нет активного запроса,"submitting" — форма отправляется,"loading" — данные загружаются.submit — функция для программной
отправки данных.
Form — компонент формы для
асинхронной отправки.
load — функция для загрузки данных
без навигации.
Пример проверки состояния запроса:
if (fetcher.state === "submitting") {
console.log("Данные отправляются...");
}
if (fetcher.state === "loading") {
console.log("Данные загружаются...");
}
Для фоновой загрузки данных используется метод
fetcher.load. Он позволяет инициировать загрузку данных с
определённого маршрута без изменения URL.
import { useEffect } from "react";
import { useFetcher } from "react-router-dom";
function Profile() {
const fetcher = useFetcher();
useEffect(() => {
fetcher.load("/api/profile");
}, []);
if (fetcher.state === "loading") return <p>Загрузка профиля...</p>;
return <div>{fetcher.data?.name}</div>;
}
fetcher.load("/api/profile") — инициирует GET-запрос к
маршруту /api/profile.fetcher.data — содержит данные после завершения
запроса.submit позволяет отправлять данные программно без формы.
Это удобно для динамических событий или кнопок, не связанных с
<form>.
function AddItemButton({ item }) {
const fetcher = useFetcher();
function handleClick() {
fetcher.submit({ item }, { method: "post", action: "/add-item" });
}
return <button onCl ick={handleClick}>Добавить</button>;
}
method и
action.useFetcher интегрируется с механизмами маршрутизации для
обработки ошибок. Если маршрут, указанный в action,
возвращает ошибку, она будет доступна через свойство
fetcher.data или через глобальный
useRouteError при необходимости централизованной
обработки.
if (fetcher.data?.error) {
return <p>Ошибка: {fetcher.data.error}</p>;
}
Состояния submitting и loading помогают
реализовать индикаторы загрузки и блокировку кнопок, предотвращая
повторную отправку формы.
useFetcher можно использовать совместно с
useEffect для оптимизации загрузки данных только при
необходимости:
useEffect(() => {
if (!fetcher.data) {
fetcher.load("/api/items");
}
}, [fetcher]);
Такой подход предотвращает повторные запросы при каждом рендере компонента.
fetcher.Form.submit и load позволяют гибко инициировать
операции без пользовательских форм.fetcher.Form для обычных асинхронных
форм.submit применять для динамических действий,
не связанных с формой.fetcher.load подходит для предварительной загрузки
данных при отображении компонента.fetcher.state для корректного
отображения состояния загрузки и отправки.fetcher.data или использовать
централизованные обработчики маршрутов для глобальной обработки.useFetcher обеспечивает мощный инструмент для
организации фоновых операций в приложениях на React Router, позволяя
отделить управление данными от маршрутизации, оптимизировать рендеры и
создавать динамичные интерактивные интерфейсы.