Getting Started
Get up and running with @navios/react-query in minutes. This guide will walk you through installation, setup, and your first type-safe query.
Installation
npm install @navios/react-query @navios/builder @tanstack/react-query zod
# or
yarn add @navios/react-query @navios/builder @tanstack/react-query zod
# or
pnpm add @navios/react-query @navios/builder @tanstack/react-query zod
tip
@navios/react-query requires @navios/builder, @tanstack/react-query, and zod as peer dependencies.
Setup QueryClient
First, set up TanStack Query's QueryClient in your app:
// App.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app */}
</QueryClientProvider>
)
}
Quick Start
Here's a complete example:
// 1. Setup API builder
import { builder } from '@navios/builder'
import { create } from '@navios/http'
import { declareClient } from '@navios/react-query'
import { z } from 'zod'
const api = builder()
api.provideClient(create({ baseURL: 'https://api.example.com' }))
// 2. Create React Query client
const client = declareClient({ api })
// 3. Define schema
const userSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
})
// 4. Create query
const getUser = client.query({
method: 'GET',
url: '/users/$userId',
responseSchema: userSchema,
processResponse: (data) => data,
})
// 5. Use in component
function UserProfile({ userId }: { userId: string }) {
const { data, isLoading, error } = getUser.use({
urlParams: { userId },
})
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>{data.name}</div>
}
What Just Happened?
- API Builder: Created a builder instance and configured the HTTP client
- React Query Client: Created a client that bridges Builder with React Query
- Schema Definition: Used Zod to define the user data shape
- Query Creation: Created a typed query with automatic query key generation
- Component Usage: Used the query hook in a React component
Using Suspense
For a cleaner API, use Suspense:
import { Suspense } from 'react'
function UserProfile({ userId }: { userId: string }) {
// useSuspense throws on error, so you need ErrorBoundary
const user = getUser.useSuspense({ urlParams: { userId } })
return <div>{user.name}</div>
}
function App() {
return (
<ErrorBoundary fallback={<div>Error!</div>}>
<Suspense fallback={<div>Loading...</div>}>
<UserProfile userId="123" />
</Suspense>
</ErrorBoundary>
)
}
Next Steps
- Overview - Learn about key concepts
- Queries - Deep dive into queries
- Mutations - Learn about mutations
- Query Keys - Understand query key management
- Invalidation - Learn about cache invalidation
Example: Complete Setup
Here's a complete setup example:
// api/index.ts
import { builder } from '@navios/builder'
import { create } from '@navios/http'
import { declareClient } from '@navios/react-query'
const api = builder()
api.provideClient(create({ baseURL: 'https://api.example.com' }))
export const client = declareClient({ api })
// api/queries/users.ts
import { client } from '../index'
import { z } from 'zod'
const userSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
})
export const getUser = client.query({
method: 'GET',
url: '/users/$userId',
responseSchema: userSchema,
processResponse: (data) => data,
})
// components/UserProfile.tsx
import { getUser } from '../api/queries/users'
export function UserProfile({ userId }: { userId: string }) {
const { data, isLoading, error } = getUser.use({
urlParams: { userId },
})
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return (
<div>
<h1>{data.name}</h1>
<p>{data.email}</p>
</div>
)
}