Reputation: 2781
I am getting the user's location (latitude/longitude) which I use to call a google geocode API, unless the user's coords change, the request is not running again, since the query it uses the user's coords as queryKey array dependecy.
the problem is that I'm running some operations in the onSuccess
query method, this method is only run when any of the queryKey dependencies change, and I mentioned this not happen.
How to run the onSuccess
method whether the queryKey dependencies change or not?
export const useGoogleReverseGeocoding = (coords) => {
const url = 'someUrl';
const request = createClient(); // axios abstraction
return useQuery({
queryKey: ['google-geocode', coords],
queryFn: request,
enabled: !!coords,
onSuccess: (data) => {
const searchTerm = removeGlobalCodeText(data?.plus_code?.compound_code);
// set searchterm in a global store. This searchterm change with
// different user actions, so if the user re-share his location
// I need to run onSuccess transformation again.
setSearchTerm(searchTerm);
},
});
};
Upvotes: 0
Views: 1985
Reputation: 4033
As I was explaining in my comment, onSuccess
can't be fired without the query itself firing again. Since certain user actions should trigger the transformations on onSuccess
, you have a couple of ways to go about this, one of them would be to move these transformations on a useEffect
hook and add some user action related flag on the dependencies array. The other proposed solution would be to invalidate the query upon these user actions, so it will be refetched and the transformations on onSuccess
will execute.
You can achieve this using useQueryClient hook which returns the current QueryClient
instance. You can invalidate the query from anywhere as long as the component is wrapped by QueryClientProvider
. For this example and for convenience, I will include this hook on useGoogleReverseGeocoding
custom hook.
Example:
Custom hook:
export const useGoogleReverseGeocoding = (coords) => {
const queryClient = useQueryClient()
const url = 'someUrl';
const request = createClient(); // axios abstraction
const geocodingData = useQuery({
queryKey: ['google-geocode', coords],
queryFn: request,
enabled: !!coords,
onSuccess: (data) => {
const searchTerm = removeGlobalCodeText(data?.plus_code?.compound_code);
// set searchterm in a global store. This searchterm change with
// different user actions, so if the user re-share his location
// I need to run onSuccess transformation again.
setSearchTerm(searchTerm);
},
});
const invalidateQueryOnAction = () => queryClient.invalidateQueries(['google-geocode'])
return { geocodingData, invalidateQueryOnAction }
};
Some component:
const dummyCoords = {
lat: 33.748997,
lng: -84.387985
}
const SomeComponent = () => {
const { geocodingData, invalidateQueryOnAction } =
useGoogleReverseGeocoding(dummyCoords)
const handleSomeUserAction = () => {
// handle action...
// Invalidate query, so the query gets refetched and onSuccess callback executes again
invalidateQueryOnAction()
}
}
PS: If @TkDodo
comes along with a different solution for this, I would suggest to go for it instead.
Upvotes: 1