Reputation: 584
I have a router state "refetch" that triggers the component to refetch its data (instead of using the cached one), but when it's done, I'd like to toggle that state back to avoid an infinite loop. What is the best way to change state parameters? Or this approach is wrong?
const { state } = useLocation<{ refetch: boolean }>()
const query = useQuery<....>()
useEffect(() => {
if (state.refetch) {
query.refetch()
state.refetch = false // feels wrong to me
}
}, [query, state])
Upvotes: 1
Views: 277
Reputation: 36
If you're using React Query, you don't need to add an useEffect for that, you can add dependencies to a query, passing an array as the query key, eg:
useQuery(['key', ...dependencies], queryFn);
Every time the dependencies change it will refetch the query.
In your case you could try useQuery(['key', state], queryFn);
If you need to stick to the refetch
of the history, you could add the toggle to the queryFn
If your function depends on a variable include it in your query key - Stack Overflow
PD: You shouldn't use an object or array as a dependency for useEffect or useMemo, etc. That will always cause an infinite loop.
You could stringify them first using JSON.stringify(foo)
, use a property of the object, maybe the length of the array. Personally, I stringify them, that way the comparison is more accurate.
Upvotes: 1
Reputation: 203322
I think instead of mutating the route state object you could issue a redirect with the refetch
state set false.
Example:
const history = useHistory();
const { pathname, state } = useLocation();
const query = useQuery<....>();
useEffect(() => {
if (state.refetch) {
query.refetch();
history.replace(pathname, { refetch: false });
}
}, [query, state]);
Upvotes: 1