How to use React Query with Astro

React Query is a powerful library for managing data fetching and state in React applications. However, integrating it with Astro can be challenging due to the unique way Astro handles component rendering using astro islands. This guide will walk you through setting up React Query in an Astro project using nanostores instead of React Context.

Creating a New Astro App and Adding Required Components

  1. Create a New Astro App:

    npm create astro@latest
    cd <your-app-folder>
    
  2. Add React Integration:

    npx astro add react
    
  3. Add an SSR Adapter: For simplicity, we will use the Node adapter.

    npx astro add node
    
  4. Install Nanostores and React Integration:

    npm install nanostores @nanostores/react
    

Creating a New Store

Create a new file query.ts in the src/stores folder to define the React Query client.

// src/stores/query.ts

import { QueryClient } from "@tanstack/react-query";
import { atom } from "nanostores";

export const queryClient = atom(new QueryClient());

This sets up a new React Query client using nanostores, which will replace React Context.

Using the Store in a Component

Create a new component Example.tsx in the src/components folder.

// src/components/Example.tsx

import { useStore } from "@nanostores/react";
import { useQuery } from "@tanstack/react-query";
import { queryClient } from "../stores/query";

export default function Example() {
  const client = useStore(queryClient);
  const { data } = useQuery(
    {
      queryKey: ["example"],
      queryFn: async () => "Hello, world!",
    },
    client
  );

  return (
    <div>
      <h1>{data}</h1>
    </div>
  );
}

In this component, we use useStore to retrieve the query client from nanostores and pass it to useQuery.

Integrating the Component in an Astro Page

Finally, import and use the Example component in your src/pages/index.astro file.

---
import { ViewTransitions } from "astro:transitions";
import Example from "../components/Example";
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>Astro</title>
    <ViewTransitions />
  </head>
  <body>
    <h1>Astro</h1>
    <Example client:only="react" />
  </body>
</html>

Important Notes

  • Use the client:only directive to ensure proper handling of the query cache and avoid hydration errors.
  • The ViewTransitions is needed to the state management, otherwise, when navigating to another page and rendering the same component, the content cached by React Query might not work as expected.

By following these steps, you can effectively use React Query in your Astro projects without encountering common issues related to React Context. This setup leverages nanostores to manage the React Query context seamlessly within Astro’s island architecture.