"Lazy Query" dependent on an event occurrence - best approach?
Hey there.
My problem is quite simple, but I struggle to find a good approach.
The case looks like this:
- user opens context menu (with right-click);
ContextMenu
is a separate component and is lying within the main App
component;
- within the context menu, there is an option - clicking on that option should result in the following sequence:
1) fetch data, dependent on the option clicked (see it as a filter, I was trying to use Zustand state management to pass the filter value);
2) on response, either do nothing at all (at the current point, no error, etc is needed to be handled) or execute a function that should use the response data to update the current state (a global one, handled by Zustand);
I was trying different ways, but didn't end up with something that works perfectly. I need the query to execute once, when the filter value changes. Was trying to build custom hooks, but was running into different problems like infinite loops, extra re-renders, etc.
If I would not use React Query, the raw solution in simple terms might be something like:
useEffect(() => {
if (filter === 'none') return
if (filter === 'all')
fetchData(data)
.then((newData) => {
setData(doSomethingWithNewData(newData))
setFilter('none')
})
.catch(() => setfilter('none'))
//etc
}, [filter])
filter
would be handled by Zustand so I could just update that on the context menu item click and the useEffect
should react whenever it is.
Also most of the stuff is async, so that should be respected too.
Thanks in advance! I'm happy to provide more information if this wouldn't be enough or is not clear.3 Replies
deep-jadeOP•2y ago
@TkDodo 🔮 I'd be happy to see your insight here, I was really eager to use the library, but couldn't set it up properly in my case.
like-gold•2y ago
maybe you could use this? https://tanstack.com/query/v4/docs/framework/react/guides/dependent-queries
Dependent Queries | TanStack Query Docs
useQuery dependent Query
Dependent (or serial) queries depend on previous ones to finish before they can execute. To achieve this, it's as easy as using the enabled option to tell a query when it is ready to run:
deep-jadeOP•2y ago
@andredewaard thanks, yeah, I probably should and I was using it, but I'm not sure how this behaves under the hood and I've been getting duplicated function calls in the end.
It's clear that useEffect will only run whenever the dependency changes. With enabled feature, what should happen if the parent component, where my custom hook with useQuery lies, re-renders and the filter value will still be 'all' (because it will only fallback to 'none' once the process is finished)?
In ideal situation, I need the useQuery hook be executed whenever filter changes. It shouldn't execute again if the parent component re-renders with filter value === 'all'. It's okay to check the enabled calculated value on mount, but on re-renders, it should only "react" to the change in filter and not execute anything again. The implementation with useEffect works reliably and is quite easy to build/understand. With useQuery, it's not as clear, because I'm not sure how useQuery actually treats these situations.
Maybe I could make use of useQuery right now if I would go with
refetch
, but that would mean I should use the useEffect with a dependency, pretty much the same solution as in the OP (but with useQuery advantages). However, the difference is that useQuery will give the data in the { data }
variable and I have to check for it within the custom hook's top level - that means that I will check for it on every re-render, instead of only when the dependency changes.
I've been going through React Query docs a lot, a lot of different examples, etc, but still cannot get an identical solution for the example in the OP that would make use of the useQuery.