Reputation: 764
I am trying to use react-query with nextjs to prefetch query on server. It works for the initial query which gets a list of items. However when I try to fetch each item inside component it only fetches it on the client side.
export default function Home() {
const { data } = useQuery("pokemons", fetchPokemons);
return (
<>
<div>
{data.map((pokemon) => (
<Pokemon key={pokemon.name} pokemon={pokemon}/>
))}
</div>
</>
);
}
export async function getStaticProps() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery('pokemons', fetchPokemons)
const fetchedPokemons = queryClient.getQueryData()
//query each pokemon
fetchedPokemons.forEach(async (pokemon) => {
await queryClient.prefetchQuery(pokemon.name, () => fetchPokemon(pokemon.url))
});
return {
props: {
dehydratedState: dehydrate(queryClient),
},
}
}
And here is code for the component which also queries each item.
const Pokemon = ({pokemon}) => {
const {data} = useQuery(pokemon.name, () => fetchPokemon(pokemon.url))
// logs only in browser, on server it is undefined
{console.log(data)}
return (
<div>
<h3>
Name - {data.name}
</h3>
<h4>Base XP - {data.base_experience}</h4>
</div>
)
}
Can you please tell me what am I doing wrong that the query doesn't execute on server or is it an issue of the library itself?
Upvotes: 2
Views: 11903
Reputation: 29028
when you use getQueryData
to get data from the cache, you need to provide the key
of the data you want to get:
await queryClient.prefetchQuery('pokemons', fetchPokemons)
const fetchedPokemons = queryClient.getQueryData('pokemons')
alternatively, you can use fetchQuery to also retrieve the data immediately
try {
const fetchedPokemons = await queryClient.fetchQuery('pokemons')
} catch (error) {
// handle error
}
Be aware that fetchQuery
throws errors (as opposed to prefetchQuery
, which does not), so you might want to handle errors somehow.
Upvotes: 3
Reputation: 764
I was able to solve this by combining two of my fetching functions into one like so
const fetchPokemons = async () => {
const { data } = await axios.get(
"https://pokeapi.co/api/v2/pokemon?limit=10&offset=0"
);
const pokemonArray = await Promise.all(
data.results.map(async (pokemon) => {
const res = await axios.get(pokemon.url);
return res.data;
})
);
return pokemonArray;
};
export default function Home() {
const { data } = useQuery("pokemons", fetchPokemons);
return (
<>
<div>
{data.map((pokemon) => (
<Pokemon key={pokemon.name} pokemon={pokemon}/>
))}
</div>
</>
);
}
export async function getStaticProps() {
const queryClient = new QueryClient();
await queryClient.prefetchQuery("pokemons", fetchPokemons);
return {
props: {
dehydratedState: dehydrate(queryClient),
},
};
}
Upvotes: 0