Проблема дублирования запросов и состояния загрузки в React-компонентах
В React-приложении используется кастомный хук useGetClients для получения списка клиентов через React Query. Этот хук вызывается из двух разных компонентов с одинаковыми параметрами.
Текущая архитектура
На странице присутствуют два основных компонента:
- Таблица кошельков (Wallets): Использует хук
useGetWallets, который внутри себя вызываетuseGetClientsдля сопоставления счетов с именами клиентов. - Форма пополнения средств (DepositFundsForm): Вызывает тот же хук
useGetClientsс идентичными параметрами для заполнения выпадающего списка в сайдбаре.
Выявленная проблема
При открытии формы пополнения средств пользователь видит два активных индикатора загрузки (спиннера): один в таблице, второй - в сайдбаре. Это происходит несмотря на то, что запрос идентичен, и данные уже должны находиться в кеше React Query. С точки зрения пользовательского опыта (UX) это выглядит некорректно и создает впечатление избыточной нагрузки.
Рассмотренные варианты решения
- Корректировка условий отображения спиннера в таблице: Показывать индикатор загрузки только на основе состояния
isAccountsFetching, игнорируяisClientsFetching. Это быстрое, но неполное решение, так как не решает проблему повторного выполнения запроса. - Разделение ключей запроса (Query Keys): Передача уникального ключа из каждого компонента для создания независимых кешей и состояний загрузки. Это устранит визуальную проблему со спиннерами, но приведет к фактическому дублированию сетевых запросов, что неоптимально для производительности.
- Вынос данных в контекст (Context Provider): Создание общего провайдера, который один раз загружает данные о клиентах и предоставляет их всем дочерним компонентам. Этот подход решает проблему дублирования запросов, но порождает новые вопросы архитектуры.
Вопросы к решению с контекстом
- Что отображать в таблице в момент первоначальной загрузки данных в провайдере? Стоит ли использовать скелетон вместо всей таблицы?
- Если форма
DepositFundsFormбудет использоваться в других частях приложения, её всегда придется оборачивать в этот провайдер. Не приведет ли это к излишней сложности и неудобству в поддержке?
Ключевой вопрос
Какой архитектурный подход будет наиболее правильным для баланса между оптимальным пользовательским опытом (отсутствие лишних спиннеров и запросов) и чистотой, поддерживаемостью кода?