I have this custom hook that used to fetch multiple requests
import dashboardApi from '@api/dashboardApi'
import { queryKeys } from '@constants/queryKeys'
import { TOP_PROJECT_SORT } from '@models/projectCost'
import { UseQueryOptions, UseQueryResult, useQuery } from '@tanstack/react-query'
import { NotifyService } from '@utils/notify'
import { AxiosError } from 'axios'
function useGetExportPDFData(
queryOptions?: UseQueryOptions<any, any, any, any>,
): UseQueryResult<any, any> {
// if top member mode is custom time range, then don't pass query and cal API of previous data
const requests = [
dashboardApi.getTopProjects({
sortBy: TOP_PROJECT_SORT.AverageCost,
order: 'desc',
limit: '6',
}),
]
return useQuery(
[queryKeys.account],
async () => {
return await Promise.all(requests)
},
{
enabled: false,
onError: (error: AxiosError) => {
NotifyService.error(error)
},
...queryOptions,
},
)
}
export default useGetExportPDFData
The problem is whenever the 2 jotai state changes (topMemberTimeRange and customDateRange), it also refetch again, although I did set enable to false, I only want to trigger this when refetch is called. How to do that?
import MainPageLayout from '@components/layout/MainPageLayout'
import PersonalRevenueHeader from '@features/personal-revenue/components/PersonalRevenueHeader'
import { TopMemberMode } from '@features/personal-revenue/constant'
import useGetExportPDFData from '@features/personal-revenue/hooks/useGetExportPDFData'
import { RevenuetMember, TableRevenueMember, TopMemberResponse } from '@models/personalRevenue'
import { calculatePercentageChange } from '@utils/common'
import { useAtom } from 'jotai'
import _ from 'lodash'
import { Outlet } from 'react-router-dom'
import pdf from './pdf'
import { customTimeRange, topMemberTimeRangeQuery } from './store'
function PersonalRevenue() {
const [topMemberTimeRange] = useAtom(topMemberTimeRangeQuery)
const [customDateRange] = useAtom(customTimeRange)
const { refetch } = useGetExportPDFData({
enabled: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
})
return (
<MainPageLayout
title="PERSONAL REVENUE"
header={<PersonalRevenueHeader exportData={exportPDF} />}
>
<Outlet />
</MainPageLayout>
)
}
3
Answers
This code is in the body of the hook, which means it will execute on every render. So every time your component renders, you call
getTopProjects(/*...*/)
. This happens no matter whether the query is enabled, since this code is unrelated to the query.If you only want this code to execute when fetching the query, then move it into the query function:
You can set the options
This options will prevent useQuery from refetching.
It’s not "useQuery" that makes the request, but this part
every time your states "topMemberTimeRange", "customDateRange" changes it calls
const { refetch } = useGetExportPDFData({ enabled: false, refetchOnWindowFocus: false, refetchOnMount: false, })
and creates a new array "requests" where you make a request.
you can pass it as a second parameter
)
or if you wont array of promises
PS: Nicholas Tower made example with array of promises more clear
)
but it looks weird