Blog>
Snippets

Implementing React Query for Data Fetching in SSR

Provide an example of using React Query to prefetch data in a server-side rendering context, highlighting setup and data fetching strategies.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Hydrate } from '@tanstack/react-query-hydration';

const queryClient = new QueryClient();
First, we import the necessary components from '@tanstack/react-query' and create a new instance of QueryClient. This client will manage the cache and synchronization for our React Query hooks.
function MyApp({ Component, pageProps }) {
  return (
    <QueryClientProvider client={queryClient}>
      <Hydrate state={pageProps.dehydratedState}>
        <Component {...pageProps} />
      </Hydrate>
    </QueryClientProvider>
  );
}
We wrap our application with QueryClientProvider and Hydrate components. QueryClientProvider makes the queryClient instance available throughout the app. Hydrate is used for dehydrating (initializing) the state from the server.
export async function getServerSideProps() {
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery(['todos'], fetchTodos);
  return {
    props: {
      dehydratedState: dehydrate(queryClient),
    },
  };
}
In getServerSideProps, we prefetch data needed for the initial render. 'fetchTodos' is an asynchronous function that fetches todo items. 'dehydrate' function prepares the state so it can be passed to the client.
import { useQuery } from '@tanstack/react-query';

function Todos() {
  const { data, error, isLoading } = useQuery(['todos'], fetchTodos);
  // UI rendering logic here
}
In our component, we use the useQuery hook to access the 'todos' query. It will use the prefetched data on the initial load, and then any subsequent refetches will go through the normal fetch process.