useFetcher для фоновых операций

useFetcher — это хук библиотеки React Router, предназначенный для выполнения фоновых операций, таких как отправка форм или загрузка данных без необходимости навигации между страницами. Он позволяет отделить процесс получения и отправки данных от маршрутизации, обеспечивая асинхронное взаимодействие с сервером и более чистую архитектуру приложения.


Основы работы с useFetcher

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-метод и путь для отправки запроса.

Свойства объекта fetcher

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 помогают реализовать индикаторы загрузки и блокировку кнопок, предотвращая повторную отправку формы.


Комбинация с useEffect и оптимизация рендеров

useFetcher можно использовать совместно с useEffect для оптимизации загрузки данных только при необходимости:

useEffect(() => {
  if (!fetcher.data) {
    fetcher.load("/api/items");
  }
}, [fetcher]);

Такой подход предотвращает повторные запросы при каждом рендере компонента.


Преимущества использования useFetcher

  • Разделение маршрутизации и операций с данными — позволяет отправлять формы и загружать данные без изменения URL.
  • Асинхронные операции — поддержка фоновых запросов с управлением состоянием.
  • Простая интеграция с компонентами форм — через fetcher.Form.
  • Контроль состояния и ошибок — облегчает реализацию индикаторов загрузки и уведомлений об ошибках.
  • Программное управление запросамиsubmit и load позволяют гибко инициировать операции без пользовательских форм.

Рекомендации по использованию

  1. Использовать fetcher.Form для обычных асинхронных форм.
  2. Программный submit применять для динамических действий, не связанных с формой.
  3. fetcher.load подходит для предварительной загрузки данных при отображении компонента.
  4. Всегда проверять fetcher.state для корректного отображения состояния загрузки и отправки.
  5. Хранить ошибки в fetcher.data или использовать централизованные обработчики маршрутов для глобальной обработки.

useFetcher обеспечивает мощный инструмент для организации фоновых операций в приложениях на React Router, позволяя отделить управление данными от маршрутизации, оптимизировать рендеры и создавать динамичные интерактивные интерфейсы.