React Query — это библиотека, которая управляет данными сервера на вашем клиенте. В этой статье я расскажу вам, что это такое, что он делает и как он помог нам управлять данными и поддерживать чистую кодовую базу здесь, в FamPay.

Привет, меня зовут Акхил Наир, я фронтенд-инженер в FamPay. И моя работа заключается в том, чтобы наши пользователи максимально комфортно взаимодействовали с нашими сервисами. И мы собираемся изучить то, что поможет нам сделать именно это в этом блоге. Итак, давайте приступим!

Что такое React-запрос?

React Query — это небольшая библиотека, которая помогает нам обрабатывать данные, которые мы извлекаем с сервера, на клиенте. Ладно, что это значит? Разве мы не можем использовать Redux или другие библиотеки управления состоянием для хранения данных сервера в глобальном состоянии и управления ими? Да, конечно, но позвольте мне провести вас через оба путешествия и показать вам, что одно так просто, а другое — беспорядок.

Сценарий

Представьте, что вы создаете Facebook. Вы работаете с сотнями маршрутов и тысячами компонентов. Предположим, вам нужны зарегистрированные пользователи display_name на 15 маршрутах. Будете ли вы делать для этого 15 отдельных вызовов API?

Использование управления состоянием ( Redux , MobX )

С Redux вы обернете все свое приложение с помощью Provider и вызовете свой API на верхнем уровне приложения, а затем используете display_name во всех необходимых местах.

Вот запутанная часть: вам нужно управлять display_name вручную во всем приложении, вам также нужно обновлять display_name каждый раз, когда вы вызываете API изменения имени, что приводит к большому количеству асинхронных ожиданий, вызовов редюсеров, состояний загрузки, состояний ошибок и т. д.

Вы даже можете пропустить обновление вручную после вызова API. Также существует вероятность того, что данные вашего клиента не синхронизированы с данными вашего сервера.

Здесь мы говорим только об одном поле данных. Представьте себе управление дюжиной полей данных, таких как баланс кошелька, онлайн-статус, изображение профиля и т. д.

С помощью управления запросами (React Query)

Теперь давайте упростим управление данными с помощью React Query. Вам нужно будет вызвать API внутри 15 компонентов, где вам нужно display_name.

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

Уникальный ключ в React Query — самая важная часть здесь. Ключом является контроль над API. С его помощью вы можете проверить запрос после вызова update display_name API. Как только запрос становится недействительным, он будет повторно загружен и обновлен во всех местах, где используется display_name. Он также будет контролировать загрузку и состояние ошибок, что вам придется делать вручную с Redux.

Миграция здесь, в FamPay

Мы в FamPay недавно перешли с MobX (State Manager) на React-Query (Query Manager), и наша кодовая база Frontend никогда не была чище.

С какими проблемами мы столкнулись?

Во-первых, мы хотели более чистый способ написания наших компонентов, нам никогда не нравилось писать isLoading, isError, данные и вручную управлять ими с состоянием записи. Проблемы только росли, если API был разбит на страницы.

Теперь с помощью React-Query мы можем управлять компонентом более понятным и удобочитаемым способом, а также обрабатывать состояния загрузки и ошибок.

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

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

На изображении ниже нам нужно обновить баланс монет, список моих выигрышей, предложения, раздачи и спиннеры. Все они находятся в своих собственных компонентах со своими конечными точками API. Кроме того, раздел «Клубы» находится на отдельной вкладке, которую также необходимо обновить, поскольку кнопка «Потянуть для обновления» находилась вверху всей страницы.

С традиционным Redux-методом в долгосрочной перспективе было бы очень сложно справиться с этим. У нас есть 8–10 вызовов API на домашней странице, и с управлением состоянием нам пришлось бы вызывать каждый API и ждать всех их ответов, а затем устанавливать их данные в глобальном состоянии, сохраняя при этом их состояния загрузки и ошибки.

Вот как весь этот процесс будет выглядеть в React Query:

Вот и все, это код для обновления/повторной загрузки всех вызовов API на заданном маршруте, а также автоматического управления состояниями isLoading и isError.

API, которые находятся на текущем маршруте, считаются активными, поэтому все, что мы делаем, это передаем active как true в параметрах вызова queryClient, и только API на этом маршруте будут предварительно выбраны, что позволяет нам ограничить вызовы API только теми, которые необходимы. Данные могут иметь глубину 10 уровней, и они все равно будут повторно извлекаться, как и ожидалось.

А теперь одна из моих любимых функций реагирующих запросов: Кэширование.

Как это работает? Вот реальный пример:

В My Winnings есть много значков, таких как Cash, Discounts, Referral и т. д. Каждый из них открывает новый маршрут и вызывает другой API. Как правило, наши пользователи постоянно нажимают на них и возвращаются назад, и мы вызывали API для получения данных по этому маршруту каждый раз, когда он открывался.

Проблема? Нет смысла снова получать API, так как данные не изменятся, пока пользователь не выполнит действие, например запрос денежного вознаграждения.

Решение? Кэшировать данные.

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

при любом связанном успехе API мы можем вызвать:

queryClient.invalidateQueries(key);

Этот key является уникальным ключом API, который необходимо аннулировать.

Мои любимые функции React Query

  • Кэширование
  • Фоновые обновления
  • Аннулирование API
  • Мутации
  • Пользовательский/выборочный ответ
  • Разбивка на страницы/дополнительная загрузка
  • Чистый код

Заключение

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

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

Если вы все еще не убеждены или считаете, что эта статья слишком длинная, вот кое-что, что поможет вам присоединиться:

  • представьте, что вы пишете компонент, который показывает ваш текущий баланс
  • используя этот компонент в 5 разных местах
  • затем добавьте кнопку обновления к другому компоненту на другой стороне приложения.
  • Затем можно щелкнуть по нему и получить обновленный баланс во всех 5 компонентах с помощью одного вызова API.

Вот оно, ребята, это волшебство.