T
TanStack3y ago
ugly-tan

is there a fetch on demand utility on react query?

I've decided the react router's useFetcher is too awkward to use when not using remix. I do like that it is event driven though. You imperatively call .load() when you want to fetch data. Is there a react query alternative to this? something like:
const query = useQuery({enabled: false})

<button onClick={() => query.refetch()}>Fetch data</button>
<div>{JSON.stringify(query.data, null, 2)}</div>
const query = useQuery({enabled: false})

<button onClick={() => query.refetch()}>Fetch data</button>
<div>{JSON.stringify(query.data, null, 2)}</div>
It's like i want useMutation but be able to get the response data back from it like useQuery
10 Replies
generous-apricot
generous-apricot3y ago
You can use a conditionally disabled query, or disable it and call refetch imperatively
ugly-tan
ugly-tanOP3y ago
if a query is disabled and i call refetch won't it do nothing?
generous-apricot
generous-apricot3y ago
It'll fetch
ugly-tan
ugly-tanOP3y ago
hmm i wish there was a useImperativeQuery
const query = useImperativeQuery({
queryFn: (payload) => axios.get(`/url?${new URLSearchParams(payload)}`)
})

<button onClick={() => query.fetch({foo: 'foo'})}>Fetch data</button>
<div>{JSON.stringify(query.data, null, 2)}</div>
const query = useImperativeQuery({
queryFn: (payload) => axios.get(`/url?${new URLSearchParams(payload)}`)
})

<button onClick={() => query.fetch({foo: 'foo'})}>Fetch data</button>
<div>{JSON.stringify(query.data, null, 2)}</div>
afraid-scarlet
afraid-scarlet3y ago
useMutation might be what you’re looking for - https://tanstack.com/query/v4/docs/react/reference/useMutation..
Overview | TanStack Query Docs
TanStack Query (FKA React Query) is often described as the missing data-fetching library for web applications, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your web applications a breeze. Motivation
ratty-blush
ratty-blush3y ago
If the goal is to still use the data in a declarative manner (displayed somewhere in the ui), I would use a conditionally disabled query (enable the query when clicking the button) as Louis suggested. But if it's truly imperative (trigger the fetch imperatively and use the result immediatelly inside a function), you might not need react query at all.
absent-sapphire
absent-sapphire3y ago
i wish there was a useImperativeQuery
okay, but that's just not how react query works. the key observers a cache entry. if you change parameters, you need to change the key. refetch can't do that. https://tkdodo.eu/blog/react-query-fa-qs#how-can-i-pass-parameters-to-refetch
React Query FAQs
Answering the most frequently asked React Query questions
ugly-tan
ugly-tanOP3y ago
yeah i realized i was being dumb and what i really was wanting was useMutation. It just didn't occur to me since i wasn't mutating anything @TkDodo 🔮 thinking about this a bit more...something like this is what i'm really after
function useCitySearch () {
return useMutation({
mutationFn: (contains: string) => {
return queryClient.ensureQueryData({
queryKey: ['city-search', contains],
queryFn: () => axios.get(`/api/cities?${new URLSearchParams({contains})}`)
})
}
})
}

const mutation = useCitySearch()

<Combobox onInputChange={mutation.mutate} options={mutation.data ?? []} />
function useCitySearch () {
return useMutation({
mutationFn: (contains: string) => {
return queryClient.ensureQueryData({
queryKey: ['city-search', contains],
queryFn: () => axios.get(`/api/cities?${new URLSearchParams({contains})}`)
})
}
})
}

const mutation = useCitySearch()

<Combobox onInputChange={mutation.mutate} options={mutation.data ?? []} />
This way i can cache the queries @Tanner Linsley what do you think about this?
absent-sapphire
absent-sapphire3y ago
You don't need to wrap it in a mutation. Just call await queryClient.ensureQueryData
ugly-tan
ugly-tanOP3y ago
🤔 but that's not a hook. not sure I understand your suggestion

Did you find this page helpful?