Гид по технологиям

Tanstack Query в React: гайд по useQuery и useMutation

5 min read Frontend Обновлено 30 Dec 2025
Tanstack Query в React: гайд по useQuery и useMutation
Tanstack Query в React: гайд по useQuery и useMutation

Ноутбук на столе. На экране видно панель с данными и графиками.

Что такое Tanstack Query

Tanstack Query — это библиотека для управления асинхронными запросами в React. Коротко: она берёт на себя логику запросов, кэширования, повторных запросов, синхронизации данных и инвалидации кэша. Основные термины:

  • QueryClient — объект, управляющий кэшем и настройками.
  • QueryClientProvider — поставляет QueryClient в дерево компонентов.
  • useQuery — хук для чтения/кэширования данных.
  • useMutation — хук для создания/обновления/удаления данных.

Установка и базовая настройка

Установите пакет через npm или yarn:

# npm
npm i @tanstack/react-query

# yarn
yarn add @tanstack/react-query

Затем создайте экземпляр QueryClient и оберните приложение в QueryClientProvider:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

const queryClient = new QueryClient()

ReactDOM.createRoot(document.getElementById('root')).render(
  
    
      
    
  
)

Важно: QueryClient можно настроить глобально (по умолчанию cacheTime = 5 минут, staleTime = 0). Эти значения удобно переопределять для конкретных типов ресурсов.

useQuery — базовый пример и жизненный цикл

useQuery позволяет выполнить GET-подобный запрос и управлять состояниями isLoading, isError, isSuccess.

Простой пример с axios и jsonplaceholder:

import React from 'react'
import axios from 'axios'
import { useQuery } from '@tanstack/react-query'

function Home() {
  const postQuery = useQuery({
    queryKey: ['posts'],
    queryFn: async () => {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts')
      return response.data
    }
  })

  if (postQuery.isLoading) return 

Загрузка...

if (postQuery.isError) return

Ошибка загрузки данных

return (

Home

{postQuery.data.map(item => (

{item.title}

))}
) } export default Home

useQuery возвращает объект с ключевыми полями: data, error, isLoading, isError, isSuccess, refetch и т. д.

Передача queryKey в queryFn

queryFn получает аргумент с queryKey — это удобно для параметризованных запросов:

useQuery({
  queryKey: ['posts', userId],
  queryFn: async ({ queryKey }) => {
    const [, userId] = queryKey
    const res = await fetch(`/api/posts?user=${userId}`)
    return res.json()
  }
})

Это стандартный паттерн для кэширования разных вариаций одного ресурса.

Управление устаревшими данными и рефетчинг

Tanstack Query позволяет гибко настраивать сроки устаревания и интервал автоматического получения данных.

Ключевые опции:

  • staleTime — время (мс), пока данные считаются свежими. По умолчанию 0 (не свежие).
  • cacheTime — сколько держится кэш после неиспользования (по умолчанию 5 минут = 300000 мс).
  • refetchInterval — периодический рефетч (мс) или false.
  • enabled — если true, запрос выполняется; если false, запрос отложен.

Примеры:

useQuery({
  queryKey: ['profile'],
  queryFn: fetchProfile,
  staleTime: 1000, // 1 секунда
  cacheTime: 1000 * 60 * 10, // 10 минут
  refetchInterval: false,
})

Если требуется постоянное обновление — используйте refetchInterval. Для событий в реальном времени лучше использовать WebSocket/Server-Sent Events и инвалидировать кэш вручную.

useMutation — создание и изменение данных

useMutation управляет POST/PUT/DELETE-операциями. Он не кэширует результат автоматически в том же смысле, что useQuery, но позволяет актуализировать кэш после успешной мутации.

Пример компонента для добавления поста:

import React from 'react'
import axios from 'axios'
import { useMutation, useQueryClient } from '@tanstack/react-query'

function AddPost() {
  const [post, setPost] = React.useState({ title: '' })
  const queryClient = useQueryClient()

  const newPostMutation = useMutation({
    mutationFn: async (newPost) => {
      const response = await axios.post('https://jsonplaceholder.typicode.com/posts', newPost)
      return response.data
    },
    onSuccess: (data) => {
      // Инвалидируем запросы, чтобы обновить список постов
      queryClient.invalidateQueries(['posts'])
    }
  })

  const handleChange = (e) => {
    setPost(prev => ({ ...prev, [e.target.name]: e.target.value }))
  }

  const handleSubmit = async (e) => {
    e.preventDefault()
    newPostMutation.mutate(post)
  }

  return (
    
) } export default AddPost

Оптимистические обновления и откат

Для лучшего UX можно применить оптимистические обновления с rollback. Паттерн:

  1. Сохранить snapshot текущих данных через queryClient.getQueryData.
  2. Немедленно обновить кэш с предполагаемым результатом через queryClient.setQueryData.
  3. При ошибке откатиться к snapshot через queryClient.setQueryData.

Пример:

const mutation = useMutation({
  mutationFn: postToServer,
  onMutate: async (newPost) => {
    await queryClient.cancelQueries(['posts'])
    const previous = queryClient.getQueryData(['posts'])
    queryClient.setQueryData(['posts'], old => [...(old || []), newPost])
    return { previous }
  },
  onError: (err, newPost, context) => {
    queryClient.setQueryData(['posts'], context.previous)
  },
  onSettled: () => {
    queryClient.invalidateQueries(['posts'])
  }
})

Дополнительные возможности и советы

  • retry — число попыток при ошибке; можно задать стратегию экспоненциального бэкоффа.
  • select — позволяет трансформировать данные до попадания в компонент.
  • enabled — отложенные запросы (например, ждать наличия id).
  • keepPreviousData — полезно при пагинации, чтобы не показывать пустой экран при смене страницы.
  • useInfiniteQuery — для ленивой загрузки страниц (infinite scroll).

Отладка и инструменты

Установите Devtools для визуализации кэша и запросов:

npm i @tanstack/react-query-devtools

Использование:

import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

// внутри провайдера

Когда Tanstack Query не подходит

  • Очень простые приложения без асинхронных вызовов — оверхед.
  • Если необходима сложная координация потоков реального времени (используйте WebSocket + локальное состояние).
  • Когда правила кэширования строго регулируются сервером и клиент не должен самостоятельно решать, что считать свежим.

Альтернативы и сравнение

  • SWR (Vercel) — похож по идеологии: кэш + повторная валидация. Легковеснее и проще для базовых кейсов.
  • useEffect + fetch/axios + собственный локальный кэш — полная свобода, но больше шаблонного кода.

Рекомендация: для большинства приложений с динамическими данными Tanstack Query ускоряет разработку и улучшает UX.

Безопасность и приватность

  • Не храните чувствительные данные в местном кэше дольше, чем требуется.
  • При работе с персональными данными учитывайте локальные законы о конфиденциальности (например, GDPR) — очищайте кэш и cookie при выходе пользователя.

Совместимость и миграция

  • Переименование React Query → Tanstack Query не меняет базовой логики; API может иметь мелкие изменения между мажорными версиями.
  • При обновлении внимательно читайте changelog и тестируйте поведение кэша и мутаций.

Практический чеклист для команды

Frontend:

  • Установить QueryClientProvider в корне приложения.
  • Выделять queryKey по ресурсам и параметрам.
  • Использовать invalidateQueries после мутаций.

Backend:

  • Стандартные эндпоинты для пагинации и фильтров помогают кэшированию.
  • Предоставлять ETag/Last-Modified, когда возможно.

QA/DevOps:

  • Тестировать сценарии офлайн и медленного соединения.
  • Проверить поведение при инвалидировании кэша и rollback.

Мини-методология внедрения (SOP)

  1. Добавить QueryClientProvider.
  2. Перенести запросы с useEffect → useQuery по одному ресурсу.
  3. Настроить staleTime/cacheTime для каждого ресурса.
  4. Реализовать useMutation с onSuccess/invalidateQueries.
  5. Добавить Devtools и покрыть тестами критичные потоки.

Критерии приёмки

  • Компоненты не делают прямых fetch/axios вызовов вне useQuery/useMutation.
  • Список и форма корректно обновляются после мутаций без ручного перезапуска страницы.
  • Поведение кеша соответствует ожиданиям (время жизни, refetch).

Короткое руководство по тестированию

  • Проверить загрузочный state (isLoading).
  • Проверить обработку ошибок (isError).
  • Тестировать optimistic update и откат при ошибке.
  • Тестировать disabled/enabled варианты запросов.

Пример плавной миграции с useEffect (паттерн)

  1. Создайте новый useQuery рядом с текущим кодом.
  2. Переключите компонент на useQuery, не удаляя старый код до успешного теста.
  3. Удалите дублирование.

Резюме

Tanstack Query сокращает шаблонный код при работе с асинхронными данными, улучшает пользовательский опыт за счёт кэширования и предоставляет мощные паттерны для оптимистических обновлений и инвалидации кэша. Для большинства динамических приложений это надёжный инструмент; в простых проектах он может быть лишним.

Важно: выбирайте стратегию staleTime и cacheTime в зависимости от критичности свежести данных и нагрузки на сервер.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Хорошее письмо — это хорошая коммуникация
Навыки письма

Хорошее письмо — это хорошая коммуникация

Ошибка «Failed to download file» в Minecraft — как исправить
Игры

Ошибка «Failed to download file» в Minecraft — как исправить

Как заблокировать игрока на Nintendo Switch
Игры

Как заблокировать игрока на Nintendo Switch

Маркеры ячеек в Excel: руководство
Software

Маркеры ячеек в Excel: руководство

Энергопанель Alexa — мониторинг энергопотребления
Умный дом

Энергопанель Alexa — мониторинг энергопотребления

Goodreads на Kindle — как связать и пользоваться
Руководство

Goodreads на Kindle — как связать и пользоваться