← Назад к вопросам

В чём разница между TanStack, Vue-query и Pinia?

2.0 Middle🔥 111 комментариев
#Vue.js

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между TanStack Query, Vue Query и Pinia

Уточнение терминологии

Это три разных инструмента для управления состоянием и данными в фронтенде, но они решают разные задачи:

  • TanStack Query (ранее React Query) — управление асинхронными данными
  • Vue Query — то же самое, но для Vue.js
  • Pinia — управление глобальным состоянием приложения

TanStack Query (React Query)

TanStack Query — это библиотека для управления асинхронными данными и кешированием в приложении. Она автоматически:

  • Получает данные с сервера
  • Кеширует результаты
  • Синхронизирует данные между несколькими местами в приложении
  • Обновляет данные автоматически
import { useQuery } from '@tanstack/react-query';

function UserProfile() {
  // TanStack Query управляет получением данных, кешем и обновлениями
  const { data: user, isLoading, error } = useQuery({
    queryKey: ['user', userId],
    queryFn: () => fetch(`/api/users/${userId}`).then(r => r.json())
  });
  
  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;
  
  return <div>User: {user.name}</div>;
}

Vue Query

Vue Query — это то же самое, что TanStack Query, но для Vue.js. Это composition API инструмент для управления асинхронными данными:

import { useQuery } from '@vue/query';

export default {
  setup(props) {
    // Vue Query — той же функциональностью, что TanStack Query
    const { data: user, isLoading, error } = useQuery({
      queryKey: ['user', props.userId],
      queryFn: () => fetch(`/api/users/${props.userId}`).then(r => r.json())
    });
    
    return { user, isLoading, error };
  }
};

Pinia

Pinia — это менеджер глобального состояния для Vue.js (замена Vuex). Она хранит все состояние приложения в одном централизованном хранилище и управляет действиями над этим состоянием:

import { defineStore } from 'pinia';

// Создаем store для управления пользователем
export const useUserStore = defineStore('user', {
  state: () => ({
    user: null,
    isLoading: false,
    error: null
  }),
  
  getters: {
    isAuthenticated: (state) => !!state.user
  },
  
  actions: {
    async fetchUser(userId) {
      this.isLoading = true;
      try {
        const response = await fetch(`/api/users/${userId}`);
        this.user = await response.json();
      } catch (e) {
        this.error = e.message;
      } finally {
        this.isLoading = false;
      }
    }
  }
});

// Использование в компонентах
import { useUserStore } from '@/stores/user';

export default {
  setup() {
    const userStore = useUserStore();
    userStore.fetchUser(1);
    
    return { userStore };
  }
};

Сравнительная таблица

ПараметрTanStack Query / Vue QueryPinia
НазначениеАсинхронные данные и кешированиеГлобальное состояние приложения
Тип данныхДанные с сервера (API)Любое состояние приложения
КешированиеВстроенное с умным инвалидированиемНет встроенного
СинхронизацияАвтоматическая синхронизация с серверомРучное управление
Размер бандла~15 KB (gzipped)~6 KB (gzipped)
DevTools поддержкаДа (отличная)Да (отличная)
Кривая обученияСредняяПологая
FrameworkReact, Vue, Svelte, etcТолько Vue
Обновление данныхАвтоматическое в фонеРучное через actions

Ключевые различия

TanStack Query/Vue Query фокусируется на асинхронных данных с сервера:

// TanStack Query автоматически:
// 1. Получает данные
// 2. Кеширует их
// 3. Синхронизирует с другими компонентами, используя то же queryKey
// 4. Обновляет в фоне (refetch)
// 5. Показывает loading/error состояния

const { data } = useQuery({
  queryKey: ['users'],
  queryFn: fetchUsers,
  staleTime: 5 * 60 * 1000,      // 5 минут в кеше
  gcTime: 10 * 60 * 1000,        // 10 минут в памяти
  refetchInterval: 1 * 60 * 1000  // Обновлять каждую минуту
});

Pinia фокусируется на централизованном управлении состоянием:

// Pinia управляет ВСЕМ состоянием приложения
// включая UI состояние, данные, настройки и т.д.

const useAppStore = defineStore('app', {
  state: () => ({
    isDarkMode: false,
    sidebarOpen: true,
    currentPage: 1,
    filters: { search: '' }
  }),
  
  actions: {
    toggleDarkMode() {
      this.isDarkMode = !this.isDarkMode;
    }
  }
});

Когда использовать TanStack Query / Vue Query

  1. Получение данных с API
  2. Кеширование ответов от сервера
  3. Синхронизация между компонентами
  4. Автоматический refetch при фокусе на окно
  5. Оптимистичные обновления
  6. Мутации (POST, PUT, DELETE) с инвалидацией кеша
import { useMutation, useQueryClient } from '@tanstack/react-query';

function UpdateUser() {
  const queryClient = useQueryClient();
  
  const mutation = useMutation({
    mutationFn: (userData) => 
      fetch(`/api/users/${userId}`, {
        method: 'PUT',
        body: JSON.stringify(userData)
      }).then(r => r.json()),
    onSuccess: () => {
      // Инвалидировать кеш, чтобы данные обновились
      queryClient.invalidateQueries({ queryKey: ['user', userId] });
    }
  });
  
  return (
    <button onClick={() => mutation.mutate({ name: 'New Name' })}>
      Update
    </button>
  );
}

Когда использовать Pinia

  1. Управление глобальным состоянием приложения
  2. UI состояние (модалки, меню, фильтры)
  3. Кросс-компонентная коммуникация
  4. Управление сложной бизнес-логикой
  5. Для Vue.js приложений
  6. Локальные данные, которые не нужно синхронизировать с сервером
import { useAuthStore } from '@/stores/auth';

export default {
  setup() {
    const auth = useAuthStore();
    
    const logout = () => {
      auth.clear(); // Очистить состояние
      router.push('/login');
    };
    
    return { auth, logout };
  }
};

Комбинированный подход (рекомендуется)

Оптимальный способ — использовать оба инструмента вместе:

// Pinia для глобального состояния (UI, auth, settings)
export const useAppStore = defineStore('app', {
  state: () => ({
    isDarkMode: false,
    user: null,
    isLoggedIn: false
  })
});

// TanStack Query для асинхронных данных (API)
function UserList() {
  const appStore = useAppStore();
  
  const { data: users } = useQuery({
    queryKey: ['users'],
    queryFn: fetchUsers,
    enabled: appStore.isLoggedIn  // Зависимость от Pinia
  });
  
  return (
    <div>
      {appStore.isDarkMode && <p>Dark mode: ON</p>}
      {users?.map(user => <UserCard key={user.id} user={user} />)}
    </div>
  );
}

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

Вместо Pinia в React:

  • Redux Toolkit
  • Zustand
  • Recoil
  • Jotai

Вместо TanStack Query:

  • SWR (Stale-While-Revalidate)
  • Apollo Client (для GraphQL)
  • Urql (для GraphQL)

Заключение

  • TanStack Query / Vue Query = управление асинхронными данными с сервера
  • Pinia = управление глобальным состоянием приложения (Vue.js только)
  • Они дополняют друг друга, а не конкурируют
  • В React используй TanStack Query + Redux/Zustand
  • В Vue используй Vue Query + Pinia