В этом посте мы рассмотрим, как React Query помог нам упростить управление данными, полученными через API, в наших приложениях React. В конце концов, он заменил Redux Thunk и наше доморощенное решение, основанное на хуках React.

Что было нашей мотивацией?

С момента появления React в мире веб-разработки две темы были приоритетными при запуске новых проектов:

  1. Глобальное управление состоянием
  2. Получение данных

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

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

Какие варианты мы оценили?

Мы хотели инвестировать в масштабируемое решение, которое позволило бы нам удалить обработку запросов API и шаблон управления глобальным состоянием, и которое будет хорошо поддерживаться TypeScript (который является стандартным языком Frontend в Personio).

По этим причинам мы проанализировали следующие варианты:

Redux Sagas: Крутая кривая обучения, требует большого количества шаблонного кода. Добавление одного асинхронного запроса приводит к изменениям в нескольких местах исходного кода, например: функция саги, функция редуктора, функция создания действия и т. Д.

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

Индивидуальное решение, основанное на хуках React: простое в использовании, небольшое количество шаблонов, однако сложно последовательно применять эту практику в большой кодовой базе. Это решение, которое мы успешно использовали, пока проект не разросся, а дерево состояний не стало более сложным. А так как это соглашение было трудно реализовать с помощью кода, потребовалась некоторая дисциплина, чтобы все было стандартизовано командой из 30+ интерфейсных инженеров.

React Query: прост в использовании, мало шаблонов, легко применять последовательно в большой кодовой базе. В отличие от Redux, ориентированного на управление глобальным состоянием, React Query ориентирован именно на управление тем, что авторы библиотеки называют состоянием сервера. Состояние сервера отражает асинхронно полученные данные, поступающие со стороны сервера, и контрастирует с состоянием клиента. Такой целевой фокус библиотеки приводит к меньшему количеству шаблонов при написании запросов API. Кроме того, в библиотеке реализовано интеллектуальное кэширование запросов, которое может еще больше помочь в повышении производительности нашего приложения. Обратной стороной использования React Query является то, что он не так широко используется, как Redux (Redux Thunk, Redux Sagas).

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

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

В качестве примера того, как мы применяем React Query в Personio, мы рассмотрим простой компонент, который выбирает и изменяет список элементов обратной связи:

Получение и отображение данных

Данные для заполнения компонента элементами списка обратной связи поступают из одной конечной точки API, полезная нагрузка которой аналогична приведенной ниже таблице:

React Query использует хуки, а для запроса данных библиотека предоставляет ловушку useQuery. Мы можем создавать многократно используемые функции запросов API, помещая вызовы useQuery в отдельные модули. , например:

Нам нужно указать уникальный ключ в качестве первого параметра функции useQuery, которым в нашем случае является ServerStateKeysEnum.Feedback. Этот ключ будет использоваться React Query для кеширования ответа от конечной точки https://example.com/feedbacks.

Теперь мы можем использовать ловушку useGetFeedbacks в компоненте, отвечающем за отображение списка отзывов:

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

Мы можем изменить функцию useGetFeedbacks, обработать обратный вызов onError и вызвать соответствующий метод рендеринга всплывающих окон:

Мутирующие данные

Подобно запросу данных из конечной точки API, мы можем использовать перехватчики React Query, заключенные в специальные модули, для обработки операций с изменяющимися данными API (создание, обновление, удаление).

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

Чтобы реализовать этот вариант использования, мы можем использовать обработчик библиотеки useMutation и обрабатывать его обратные вызовы onSuccess и onError для отображать всплывающие сообщения. Наконец, нам нужно обновить кэшированный список элементов обратной связи, чтобы включить в него вновь созданный элемент:

С финальной версией компонента списка отзывов можно ознакомиться здесь.

Заключение

В Personio мы упростили большую часть кода наших микро-интерфейсов, используя React Query для обработки состояния сервера. Существенным фактором, способствовавшим широкому внедрению React Query, стал тот факт, что мы не используем тяжелое управление состоянием клиентов, а большая часть данных часто синхронизируется с серверной частью. Это сделало React Query очень подходящим для нас.

Если вы хотите узнать больше о React Query, я приглашаю вас проверить официальную документацию и посмотреть Выступление Таннера Линсли на React Summit, где он представляет React Query и показывает более практический пример.

Если вам нравится работать над подобными проблемами, ознакомьтесь с нашими открытыми вакансиями и присоединяйтесь к нам в Personio - самой ценной компании в области HR-технологий в Европе!