I am new at React Query, but I faced a problem that I couldn't find an answers yet. Well, I have a query that can be done in three endpoints different- Let say, ['pokemons', 'kanto'] / ['pokemons', 'johto'] and ['pokemons', 'favorites']
I have a tab that change which request will be made
const { data, isLoading } = usePokemonList(type)
And based on that request I make my query
export const usePokemonList= (queryType: string) => {
const options = {
cacheTime: 1 * 60 * 1000,
staleTime: 1 * 60 * 1000,
retry: 1
}
const queryClient = useQueryClient()
const { favorites } = useFavorites()
React.useEffect(() => {
console.log('favorites inside context', favorites) /* Console log at query function */
queryClient.invalidateQueries({ queryKey: ['pokemons', 'favorites'] })
}, [favorites, queryType, queryClient])
return useQuery<any>({
queryKey: ['pokemons', queryType],
queryFn: () => getData(queryType, favorites),
...options
})
}
In the fetch function I do a conditionaly to see if has some pokemon favorited, if yes, I want to load that specific fetch function
export const getData = async (favorites: number[]) => {
console.log('favorites on fetch', favorites) /* Console log at fetch function */
if(favorites.length > 0)
return await(await(fetch('******')).json()
return await (
await fetch('**************')
).json()
}
The problem is that pokemons favorites are been storaged at localstorage and loaded in React Context, and works great. The problem is when I update them, and with that I want to invalidate query and load again with the newers pokemons favorites, but for some reason, the data that comes to fetch function is not the right one, it is outdated
In console log you can see that the favorites data inside query block, which is responsible for invalidate query when favorites changes(useEffect), but for some reason in the fetch function comes the outdated array.
How can I redo/ invalidate that query when favorites context changes? Can I pass the array to fetch function through invalidate query
method?
When searching I found that query key could be wrong, but I don't think that's my case, because the request are been made, but only with the old data.
I want that I can invalidate that query every time favorites context array changed one of it's items
The query key, will be the same = ['pokemons', 'favorites']. What will change is data passed on parameters for fetch query
CodePudding user response:
You're passing your parameters directly to your query function. Stop doing that. The parameters to your query function should be routed through your query key. Then there's no need to invalidate when you change parameters. Query keys are important. Use them more/properly.
e.g.
// define a function outside the hook..
const getDataQuery = ({queryKey: [,{queryType, favorites}]}) =>
getData(queryType, favorites)
// Then in the custom hook remove that unnecessary useEffect and instead..
return useQuery<any>({
queryKey: ['pokemons', {queryType, favorites}],
queryFn: getDataQuery,
...options
})
Then whenever the queryType changes or whenever favorites changes the query will update.