DEV Community

Cover image for Integrating React Query with Next.js 🚀
Bhavesh Yadav
Bhavesh Yadav

Posted on

Integrating React Query with Next.js 🚀

Hey folks, Recently i was working on a freelance project and in that i learned so many things about react query, i used react query before but just for the sake of knowing it, never used it in a real life project, when i used it with Nextjs then i got to know its true strength and today i'll tell you how you can integrate it with your Nextjs project.

So without further ado, let's get started!

Setting up the Next.js project

First, let's set up a brand new Next.js project. Open up the terminal and run the following commands:

 npx create-next-app react-query-tut
 cd react-query-tut
Enter fullscreen mode Exit fullscreen mode

Once the project is set up, let's install the necessary dependencies by running the following commands:

 npm install react-query
 npm install react-query-devtools
Enter fullscreen mode Exit fullscreen mode

react-query-devtools is optional you don't have to install it its just a helper tool for which you can use in browser.

Setting up the Query Client Provider

Now, let's set up the QueryClient provider in the layout.tsx file. Import the QueryClientProvider and QueryClient from react-query:

 import { QueryClientProvider, QueryClient } from 'react- 
 query';
Enter fullscreen mode Exit fullscreen mode

Since the QueryClientProvider is a client-side component, it won't work in a server component directly. However, we can still wrap a client component around a React server component. Create a provider.tsx file in the util folder and update it as follows:

 import { QueryClient, QueryClientProvider } from 'react- 
 query';

 const queryClient = new QueryClient();

 export function QueryClientWrapper({ children }) {
        return (
            <QueryClientProvider client={queryClient}>
                {children}
            </QueryClientProvider>
        );
    }
Enter fullscreen mode Exit fullscreen mode

Save the provider.tsx file. In the main layout.tsx file, import the QueryClientWrapper and wrap it around the children components:

  import { QueryClientWrapper } from './utils/provider';

    export default function Layout({ children }) {
        return (
            <QueryClientWrapper>
                {/* Rest of the code */}
            </QueryClientWrapper>
        );
    }
Enter fullscreen mode Exit fullscreen mode

This setup allows us to use the QueryClient provider in our Next.js project.

Fetching Data with React Query

In the Layout component, we'll set up server actions to fetch data and use React Query to manage the data globally. Assuming you have a server folder with a server action file, here's an example of how to fetch products data:

    import { useQuery } from 'react-query';
    import { getProducts } from '../server/server-actions';

    // ...

    export default function Layout({ children }) {
        // ...

        const { data, error } = useQuery('products', getProducts);

        if (error) {
            return <h2>{error.message}</h2>;
        }

        if (!data) {
            return <h2>Loading...</h2>;
        }

        return (
            <>
                {/* Render your components using the fetched data */}
            </>
        );
    }
Enter fullscreen mode Exit fullscreen mode

In this example, we used the useQuery hook to fetch the products data and stored it in the data variable. We also handled error and loading states. You can now use the data to render your components as needed.

Wrapping Components with Hydration Boundary

The previous method required passing down props and setting up the initial data. To simplify this process, we can use a hydration boundary to handle the client-side hydration for us. Here's how to do it:

Clean up the props in Layout and remove the need to pass initial data:

    import { dehydrate, Hydrate } from 'react-query/hydration';
    import { QueryClient } from 'react-query';

    // ...

    export default function Layout({ children }) {
        // ...

        const queryClient = new QueryClient();
        const products = await queryClient.fetchQuery('products', getProducts);

        // ...

        return (
            <Hydrate state={dehydrate(queryClient)}>
                {/* Rest of the code */}
            </Hydrate>
        );
    }
Enter fullscreen mode Exit fullscreen mode

In this example, we're using the Hydrate component from react-query/hydration to handle hydration. We initialize a new QueryClient, fetch the products data, and pass the dehydrated state to the Hydrate component.

That's all for today! Thank you so much for reading. If you enjoyed this guide, don't forget to drop a like, follow and comment any questions you have below.

Stay tuned for upcoming blog! Till then

Happy Coding!

Top comments (0)