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
-
Create a New Astro App:
npm create astro@latest cd <your-app-folder>
-
Add React Integration:
npx astro add react
-
Add an SSR Adapter: For simplicity, we will use the Node adapter.
npx astro add node
-
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.