javascript

react-query vs SWR и избавимся ли мы от Redux?

  • суббота, 2 сентября 2023 г. в 00:00:16
https://habr.com/ru/articles/758360/
react-query vs SWR
react-query vs SWR

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

react-query

react-query — это мощная библиотека для управления состоянием данных в React-приложениях. Она предоставляет простые и эффективные инструменты для работы с данными, получаемыми с сервера, и упрощает взаимодействие с API-запросами. Ниже познакомимся с базовыми фичами данной библиотеки:

Кеширование данных: Одна из основных возможностей react-query — это кеширование данных. При выполнении запросов к серверу библиотека автоматически кэширует полученные данные. Это позволяет избежать повторных запросов на сервер при обращении к тем же данным в разных частях приложения. Кэш react-query также автоматически инвалидируется при обновлении данных на сервере или вручную с помощью инвалидации.

// инвалидация
queryClient.invalidateQueries()

Автоматическое обновление данных: react-query предоставляет механизм автоматического обновления данных на основе определенных событий. Когда выполняется запрос на сервер, библиотека автоматически обновляет кэшированные данные при успешном завершении запроса, мутации или ручных вызовах обновления. Это позволяет всегда иметь актуальные данные в приложении.

Повторные запросы: В случае ошибок при выполнении запроса react-query предоставляет механизм повторных запросов, который автоматически попытается повторить запрос. Это особенно полезно при работе с нестабильным интернет-соединением или временными проблемами на стороне сервера. А так же можно настроить интервал между повторными запросами или указать максимальное количество повторов в настройках.

Оптимистические обновления: react-query поддерживает оптимистические обновления данных. Это позволяет обновлять кэшированные данные немедленно, еще до того, как запрос на сервер будет завершен. Это создает плавное впечатление для пользователей и повышает отзывчивость интерфейса.

Обработка ошибок и повторные запросы: Библиотека упрощает обработку ошибок при выполнении запросов. Она предоставляет механизм повторных запросов при ошибках, что позволяет автоматически попробовать повторить запрос для получения данных. Это особенно полезно при работе с нестабильным интернет-соединением или временными проблемами на стороне сервера.

Гибкая настройка запросов: Библиотека предоставляет гибкие средства для настройки запросов, позволяя контролировать кэширование, время жизни данных, политики повторных запросов и многое другое.

// установка значения по умолчанию глобально
import { QueryClient } from '@tanstack/react-query';

const queryClient = new QueryClient({
   defaultOptions: {
      queries: {
      staleTime: Infinity,
    },
  },
});

// установка значения по умолчанию для
// определенных запросов
queryClient.setQueryDefaults(
  ['todos'], { staleTime: 3000 }
)

Мутации: react-query поддерживает мутации, позволяя легко выполнять изменения данных на сервере. Мутации представляют собой специальные функции, которые выполняют запросы на сервер для изменения данных, и автоматически обновляют соответствующий кэш после успешного завершения мутации.

Интеграция с React: react-query разработана специально для работы с React и интегрируется с ним без проблем. Она предоставляет хуки и компоненты, которые позволяют удобно взаимодействовать с данными и отображать их в интерфейсе React-компонентов.

// пример использования библиотеки в проекте
import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const { isLoading, error, data } = useQuery({
    queryKey: ['repoData'],
    queryFn: () =>
      fetch('https://api.github.com/repos/TanStack/query').then(
        (res) => res.json(),
      ),
  })

  if (isLoading) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>✨ {data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
    </div>
  )
}
// пример GET, POST запросов
import {
  useQuery,
  useMutation,
  useQueryClient,
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'
import { getTodos, postTodo } from '../my-api'

const queryClient = new QueryClient()

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

function Todos() {
  const queryClient = useQueryClient()

  const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })

  // Мутации
  const mutation = useMutation({
    mutationFn: postTodo,
    onSuccess: () => {
      // Инвалидация и обновлени данных 
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
  })

  return (
    <div>
      <ul>
        {query.data?.map((todo) => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>

      <button
        onClick={() => {
          mutation.mutate({
            id: Date.now(),
            title: 'Do Laundry',
          })
        }}
      >
        Add Todo
      </button>
    </div>
  )
}

render(<App />, document.getElementById('root'))

SWR

SWR (Stale-While-Revalidate) — это библиотека для управления состоянием данных в React-приложениях, которая ориентирована на кеширование данных и автоматическую валидацию. Она предоставляет простой и эффективный способ работы с данными, получаемыми с сервера, и упрощает обновление данных в интерфейсе приложения. Ниже познакомимся с базовыми фичами данной библиотеки:

Кеширование данных: Одной из основных возможностей SWR является кеширование данных, получаемых с сервера. Когда выполняется запрос на сервер, библиотека автоматически кэширует полученные данные. Это позволяет избежать повторных запросов на сервер при обращении к тем же данным в разных частях приложения.

Автоматическая валидация данных: SWR использует стратегию “Stale-While-Revalidate”, что означает, что она возвращает старые данные из кэша (если они доступны) и одновременно запускает повторный запрос на сервер для получения актуальных данных. Таким образом, пользователь всегда видит старые данные, даже если сервер уже вернул новые. Это позволяет предоставить пользователю мгновенный отклик и актуальные данные после завершения повторного запроса.

Повторные запросы: В случае ошибок при выполнении запроса SWR предоставляет механизм повторных запросов, который автоматически попытается повторить запрос. Это особенно полезно при работе с нестабильным интернет-соединением или временными проблемами на стороне сервера.

Оптимистические обновления: SWR также поддерживает оптимистические обновления данных. Это означает, что при обновлении данных на сервере, она моментально обновляет данные в кэше и показывает пользователю обновленные данные без ожидания ответа от сервера. После успешного завершения запроса на сервер, кэш автоматически обновляется с актуальными данными.

Политики повторных запросов: SWR позволяет гибко настраивать повторные запросы с помощью различных политик. Например, вы можете установить интервал между повторными запросами или указать максимальное количество повторов.

Интеграция с React: SWR разработана для интеграции с React и предоставляет хук useSWR(), который позволяет удобно взаимодействовать с данными и обрабатывать состояние запросов.

const fetcher = (...args) => fetch(...args).then(res => res.json());

//пример использования библиотеки в проекте
import useSWR from 'swr'
 
function Profile () {
  const { data, error, isLoading } = useSWR('/api/user/123', fetcher)
 
  if (error) return <div>ошибка загрузки</div>
  if (isLoading) return <div>загрузка...</div>
 
  // рендер данных
  return <div>привет, {data.name}!</div>
}

Теперь, давайте сравнивать эти две библиотеки и определить, какой лучше выбрать:

Как мы поняли, основной упор библиотеки react-query делается на управление данными на клиентской стороне приложения, особенно на работу с данными, получаемыми с сервера (API-запросы). react-query предлагает мощные средства для кеширования данных, автоматической инвалидации кэша и обработки запросов.

SWR в первую очередь ориентирована на кеширование и автоматическую валидацию данных, получаемых с сервера. Она предоставляет удобные средства для кеширования и повторных запросов данных с поддержкой стратегии “Stale-While-Revalidate” (сохранение старых данных, пока выполняется повторный запрос).

Также react-query предоставляет гибкие средства для настройки запросов и поддерживает мутации, позволяя легко выполнять изменения данных на сервере, для этого react-query предоставляет хуки (useMutation()useQuery()) и компоненты для удобного взаимодействия с запросами и мутациями. SWR в свою очередь предоставляет только один хук — useSWR, который позволяет выполнять запросы и автоматически кэшировать данные, а также обрабатывать их обновления и ошибки.

Итог

В общем, если ваш проект огромный и имеет много GET/POST запросов, то лучше использовать react-query, если проект не большой и не имеет много запросов, то лучше выбирать SWR. Всё зависит от объем и функциональность проекта.

Теперь ответим на самый главный вопрос: «Избавимся ли мы от Redux?» На самом деле полностью избавиться от Redux не получится, но в какой‑то мере, да, избавимся. Как? Во всех запросах, где используется react‑query/SWR использовать Redux не нужно, эти библиотеки сами все данные берут из бэкенда и работают в качестве “state manager”-а, а так же плюс к этому кешируют данные, что это даже очень выгодно.