Idris
Idris

Reputation: 518

How to handle multiple dehydrated queries using react-query in next JS getServersideProps

I am using react-query in conjunction with Next JS getServerSideProps to fetch data before a page loads using the hydration method specified in the docs like this:

// Packages
import { dehydrate, QueryClient } from '@tanstack/react-query';

// Hooks
import { useGetGoogleAuthUrl, useGetMicrosoftAuthUrl } from '../hooks/auth';
import { getGoogleAuthUrl, getMicrosoftAuthUrl } from '../hooks/auth/api';

export async function getServerSideProps({ req, res }) {
  const queryClient = new QueryClient();
  const microsoftAuthQueryClient = new QueryClient(); // Not working
  
  await queryClient.prefetchQuery(['getGoogleAuthUrl'], getGoogleAuthUrl);
  await microsoftAuthQueryClient.prefetchQuery(['getMicrosoftAuthUrl'], getMicrosoftAuthUrl); // Not working

  return {
    props: {
      dehydratedState: dehydrate(queryClient),
      dehydratedMicrosoftAuthState: dehydrate(microsoftAuthQueryClient), // Not working
    },
  };
}

export default function Signin() {
  const date = new Date();
  const { data: googleAuthData } = useGetGoogleAuthUrl();
  const { data: microsoftAuthData } = useGetMicrosoftAuthUrl();

  console.log(googleAuthData); // logs actual data on mount and data is immediately available
  console.log(microsoftAuthData); // logs undefined before eventually logging data after being successfully fetched with the useGetMicrosoftAuthUrl() query
  


  return (
    //Page content
  );
}

How do I make it work as it is supposed to work. Is it not possible to make multiple requests in getServersideProps using react-query hydration method?

Thank you so much in advance

Upvotes: 3

Views: 4738

Answers (1)

TkDodo
TkDodo

Reputation: 28883

You would just use the same queryClient and prefetch both queries into it, then hydrate just the one:

export async function getServerSideProps({ req, res }) {
  const queryClient = new QueryClient();
  
  await queryClient.prefetchQuery(['getGoogleAuthUrl'], getGoogleAuthUrl);
  await queryClient.prefetchQuery(['getMicrosoftAuthUrl'], getMicrosoftAuthUrl);

  return {
    props: {
      dehydratedState: dehydrate(queryClient),
    },
  };
}

This however fetches them one after the other, so you might want to await them in Promise.all:

await Promise.all([
  queryClient.prefetchQuery(['getGoogleAuthUrl'], getGoogleAuthUrl),
  queryClient.prefetchQuery(['getMicrosoftAuthUrl'], getMicrosoftAuthUrl)
])

Upvotes: 7

Related Questions