React Query — мощный инструмент для управления состоянием данных в React-приложениях, который предоставляет удобные способы работы с запросами и мутациями. Используя useMutation
и invalidateQueries
, можно обновлять кэшированные данные после выполнения мутаций. В этой статье мы рассмотрим, как настроить useMutation
таким образом, чтобы после завершения мутации можно было автоматически вызывать invalidateQueries
, тем самым обеспечивая синхронизацию данных.
Основы использования useMutation и invalidateQueries
useMutation
— это хук, предоставляемый React Query для выполнения изменений данных, таких как создание, обновление или удаление записей. После выполнения мутации нужно обновить кэш, чтобы данные оставались актуальными. Здесь на помощь приходит метод invalidateQueries
, который позволяет пометить определённые запросы как «неактуальные» и принудительно их обновить, запрашивая данные заново.
Пример базовой настройки useMutation
Рассмотрим простой пример мутации с использованием useMutation
. Предположим, у нас есть API для создания новых задач. Настроим мутацию для отправки запроса на создание новой задачи:
import { useMutation } from 'react-query';
function useCreateTask() {
return useMutation((newTask) => fetch('/api/tasks', {
method: 'POST',
body: JSON.stringify(newTask),
headers: { 'Content-Type': 'application/json' },
}).then(res => res.json()));
}
Здесь мы создаём хук useCreateTask
с помощью useMutation
. Этот хук будет отправлять данные о новой задаче на сервер, и по завершении запроса данные кэшируются.
Использование onSuccess и invalidateQueries для обновления данных
Чтобы после создания новой задачи обновить список задач, необходимо настроить useMutation
так, чтобы он вызывал invalidateQueries
для обновления соответствующего кэша. Используем метод onSuccess
в useMutation
, чтобы после успешного выполнения мутации триггерить обновление списка задач.
Пример мутации с invalidateQueries
Рассмотрим, как настроить useMutation
для вызова invalidateQueries
при успешном создании задачи:
import { useMutation, useQueryClient } from 'react-query';
function useCreateTask() {
const queryClient = useQueryClient();
return useMutation(
(newTask) => fetch('/api/tasks', {
method: 'POST',
body: JSON.stringify(newTask),
headers: { 'Content-Type': 'application/json' },
}).then(res => res.json()),
{
onSuccess: () => {
queryClient.invalidateQueries('tasks');
}
}
);
}
В этом примере после успешного выполнения мутации мы вызываем queryClient.invalidateQueries('tasks')
, чтобы принудительно обновить данные по ключу 'tasks'
. Это заставит React Query повторно выполнить запрос на получение списка задач, обеспечивая актуальность данных.
Как использовать invalidateQueries для обновления нескольких запросов
В некоторых случаях после выполнения мутации необходимо обновить несколько кэшированных запросов. Например, если в приложении есть два отдельных списка задач, то после добавления новой задачи нужно обновить оба. Для этого можно использовать invalidateQueries
с несколькими ключами.
Пример обновления нескольких запросов после выполнения мутации:
function useCreateTask() {
const queryClient = useQueryClient();
return useMutation(
(newTask) => fetch('/api/tasks', {
method: 'POST',
body: JSON.stringify(newTask),
headers: { 'Content-Type': 'application/json' },
}).then(res => res.json()),
{
onSuccess: () => {
queryClient.invalidateQueries('tasks');
queryClient.invalidateQueries('userTasks');
}
}
);
}
Здесь метод onSuccess
триггерит invalidateQueries
для двух ключей: 'tasks'
и 'userTasks'
. Это позволяет обновить несколько запросов одновременно после мутации.
Другие методы обновления данных после мутаций
Помимо invalidateQueries
, React Query предоставляет и другие методы для управления кэшем после мутаций, такие как setQueryData
и refetchQueries
. Например, setQueryData
позволяет обновить кэшированные данные сразу после выполнения мутации, минуя повторный запрос.
Пример использования setQueryData
:
function useCreateTask() {
const queryClient = useQueryClient();
return useMutation(
(newTask) => fetch('/api/tasks', {
method: 'POST',
body: JSON.stringify(newTask),
headers: { 'Content-Type': 'application/json' },
}).then(res => res.json()),
{
onSuccess: (data) => {
queryClient.setQueryData('tasks', (old) => [...(old || []), data]);
}
}
);
}
В этом примере setQueryData
позволяет добавить новую задачу непосредственно в кэш, что может быть полезно, если вы хотите избежать лишнего запроса к серверу. Такой подход может быть эффективен для быстрого обновления данных в реальном времени.
Заключение
Использование useMutation
и invalidateQueries
в React Query позволяет легко управлять кэшем после мутаций и поддерживать актуальность данных. Этот подход хорошо подходит для проектов с частыми изменениями данных, например, в управлении задачами, комментариями или пользовательскими действиями. Если вас интересуют вакансии для React разработчиков или хотите развить навыки работы с React Query, эти методы помогут создать более производительные и эффективные приложения. Изучение различных подходов к управлению данными, включая серверный рендеринг, может также быть полезным. Подробнее читайте в статье о SSR без Next.js.