Как грамотно обрабатывать isFetching для одного и того же запроса в нескольких компонентах (React Query)?

Ссылка скопирована
0 ответов

Есть запрос:

export const useGetClients = (params?: GetClientsRequest) => useQuery({ queryKey: ['clients', 'list', params], queryFn: () => ClientClient.getClientApiInstance().getClients(params), });

По вводным: на странице два основных компонента: таблица и кнопка, открывающая сайдбар.

Таблица:

const Wallets = () => { const { wallets, isLoading, isFetching } = useGetWallets(); return ( <div className="flex flex-col gap-4"> <div className="flex flex-wrap items-center justify-between gap-2"> <DepositFundsButton /> </div> <DataTable columns={Columns} data={wallets} isLoading={isLoading} isFetching={isFetching} /> </div> ); };

Где:

export const useGetWallets = () => { const { data: accounts, isLoading: isAccountsLoading, isFetching: isAccountsFetching, } = useGetLedgerAccounts(); const { data: clients, isLoading: isClientsLoading, isFetching: isClientsFetching, } = useGetClients({ clientType: ClientType.Client, }); const accountsWithClientName: AccountWithClientName[] = accounts && clients ? accounts.map((account) => ({ ...account, context: { ...account.context, ...(account.context.clientId && { clientName: clients.clients.find( (client) => client.id === account.context.clientId, )?.name, }), }, })) : []; return { wallets: accountsWithClientName, isLoading: isAccountsLoading || isClientsLoading, isFetching: isAccountsFetching || isClientsFetching, }; };

По вводным: при нажатии на кнопку Deposit funds открывается сайдбар с формой.
По вводным: в форме тот же запрос вызывается повторно (с теми же параметрами), чтобы получить список клиентов для выпадающего списка:

export const DepositFundsForm = ({ onClose }: DepositFundsFormProps) => { const { data, isFetching: isClientsFetching } = useGetClients({ clientType: ClientType.Client, }); return ( <> <Form {...methods}> <form className="space-y-6 overflow-y-auto px-4"> <SelectField name="clientId" loading={isClientsFetching} control={control} label="Client" placeholder="Client" options={clientOptions} className="min-w-[300px]" /> </form> </Form> <SheetFooter> <SheetClose asChild> <Button variant="secondary">Cancel</Button> </SheetClose> <Button onClick={handleSubmit(onSubmit)} isLoading={isSubmitting}> Deposit </Button> </SheetFooter> </> ); };

Проблема:
По вводным: когда форма открыта, я вижу два спиннера — один в таблице и второй в сайдбаре. С UX точки зрения это выглядит неправильно, ведь запрос одинаковый и данные уже есть в кеше.

Возможные решения:
Сейчас ситуация такая: - Показывать спиннер в таблице только если isAccountsFetching, а не при isAccountsFetching || isClientsFetching.
По вводным: - Передавать дополнительный ключ запроса (query key) из таблицы или сайдбара, чтобы у них были разные ключи и независимые состояния.
По вводным: - Обернуть таблицу и кнопку с сайдбаром в контекст-провайдер, где данные клиентов будут загружаться один раз и шариться между компонентами.
По вводным: в случае с последним решением возникают вопросы:
Нужно понять: a) что показывать, пока в провайдере идёт загрузка клиентов — скелетон вместо таблицы?
По вводным: b) если форма будет использоваться в других местах, нужно всегда оборачивать её в провайдер, что может быть неудобно

Вопрос:
Нужно понять: какой подход здесь будет наиболее правильным с точки зрения UX и архитектуры кода?

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно