Integrating React Query with Next.js 🚀
Tags: webdev, reactquery, programming, datafetching
Published: 2024-01-15 09:10:01

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
```

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
```

> `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`:

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

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:

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

 const queryClient = new QueryClient();

 export function QueryClientWrapper({ children }) {
        return (
            <QueryClientProvider client={queryClient}>
                {children}
            </QueryClientProvider>
        );
    }
```

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

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

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

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:

```jsx
    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 */}
            </>
        );
    }
```

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:

```jsx
    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>
        );
    }
 ```

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!