| sidebar_position | 2 |
|---|---|
| sidebar_label | useQuery() |
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
The Hook enables you to perform asynchronous data fetching operations. It automatically handles loading states, caching, and data invalidation, significantly simplifying request in React. See the TanStack useQuery(...) 🌴 documentation for more details.
const query = api.<service>.<operation>.useQuery(
parameters,
queryOptions
)UseQueryResult object, see the TanStack UseQueryResult 🌴
-
parameters: { path, query, header, body } | QueryKey | void- Required only if OpenAPI specification defines required parameters
- If the operation has no required parameters according to OpenAPI, you can omit this argument
parameterswill be used to generate theQueryKey- For operations generated with
--queryable-write-operations, query parameters may also includebody - In that mode,
bodyis part of the query key and cache identity for query hooks and query-client methods - Mutation calls keep
bodyas a separate top-level argument - Instead of an object with
{ path, query, header, body }, you can pass aQueryKeyas an array which is also strictly-typed
-
queryOptions?: UseQueryOptions- Optional, represents the options of the useQuery(...) 🌴 Hook
queryOptions.queryFncould be provided to override the defaultqueryFnused by Qraft
- Optional, represents the options of the useQuery(...) 🌴 Hook
:::tip
By default, useQuery hooks are only generated for read operations (GET method). If you want to use query
hooks for write operations (POST, PUT, PATCH methods), use the --queryable-write-operations CLI option
during code generation.
:::
parameters} default>
```tsx title="src/ApprovalPolicyName.tsx"
import { createAPIClient } from './api'; // generated by OpenAPI Qraft CLI
import { requestFn } from '@openapi-qraft/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
const api = createAPIClient({
requestFn,
queryClient,
baseUrl: 'https://api.sandbox.monite.com/v1',
});
function ApprovalPolicyName() {
/**
* `<service>.<operation>.useQuery(...)` initiates the request to retrieve data:
* ###
* GET /approval_policies/321?items_order=asc&items_order=desc
* x-monite-version: 1.0.0
*/
const { data, error, isPending } =
api.approvalPolicies.getApprovalPoliciesId.useQuery(
{
header: {
"x-monite-version": "1.0.0",
},
path: {
approval_policy_id: "123",
},
query: {
items_order: ["asc", "desc"],
},
},
);
if (isPending) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return <div>Approval Policy: {data?.name}</div>;
}
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<ApprovalPolicyName />
</QueryClientProvider>
);
}
```
QueryKey}>
Using the Query Key (array) as an arguments for the `useQuery` is useful
with combination of [`api...getQueryKey(...)`](../query-client/getQueryKey.mdx) method
when shared Query Key is needed.
```tsx title="src/ApprovalPolicyName.tsx"
import { createAPIClient } from './api'; // generated by OpenAPI Qraft CLI
import { requestFn } from '@openapi-qraft/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
const api = createAPIClient({
requestFn,
queryClient,
baseUrl: 'https://api.sandbox.monite.com/v1',
});
function ApprovalPolicyName() {
/**
* `<service>.<operation>.useQuery(...)` initiates the request to retrieve data:
* ###
* GET /approval_policies/123?items_order=asc&items_order=desc
* x-monite-version: 2.0.0
*/
const { data, error, isPending } =
api.approvalPolicies.getApprovalPoliciesId.useQuery(
[
{
method: "get",
url: "/approval_policies/{approval_policy_id}",
},
{
header: {
"x-monite-version": "2.0.0",
},
path: {
approval_policy_id: "321",
},
query: {
items_order: ["asc", "desc"],
},
},
],
);
if (isPending) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return <div>Approval Policy: {data?.name}</div>;
}
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<ApprovalPolicyName />
</QueryClientProvider>
);
}
```
body}>
When using the `--queryable-write-operations` option, you can use `useQuery` with write operations like _POST_, _PUT_, _PATCH_, etc.
This is particularly useful for APIs that use _POST_ for read operations (like GraphQL or some RPC-style APIs).
#### Why POST for reading data?
Some APIs, particularly GraphQL, use _POST_ requests for reading data instead of _GET_. This design is often chosen for several reasons:
- Complex query structures are better sent in a request body than in a URL
- Query strings have length limitations in some browsers and servers
In this example, we're using _POST_ to fetch product data by sending search criteria in the request `body`:
```tsx title="src/SearchProducts.tsx"
import { createAPIClient } from './api'; // generated by OpenAPI Qraft CLI
import { requestFn } from '@openapi-qraft/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
const api = createAPIClient({
requestFn,
queryClient,
baseUrl: 'https://api.sandbox.monite.com/v1',
});
function SearchProducts() {
/**
* `<service>.<operation>.useQuery(...)` initiates a POST request for searching products:
* ###
* POST /products/search
*
* {
* "query": "laptop",
* "filters": {
* "minPrice": 500,
* "category": "electronics"
* }
* }
*/
const { data, error, isPending } =
api.products.postProductsSearch.useQuery({
body: {
query: "laptop",
filters: {
minPrice: 500,
category: "electronics"
}
},
});
if (isPending) {
return <div>Loading products...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return (
<div>
<h2>Search Results</h2>
<ul>
{data?.products.map(product => (
<li key={product.id}>
{product.name} - ${product.price}
</li>
))}
</ul>
</div>
);
}
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<SearchProducts />
</QueryClientProvider>
);
}
```
#### ‼️ Non-serializable values in body
If you plan to use non-serializable values (like `FormData`, `Blob`, `File`) in the `body` parameter, be aware that
they cannot be reliably used to form `QueryKey`. TanStack Query requires Query Keys to be serializable primitives.
In such cases, it's better to use `useMutation` instead of `useQuery`.
If you really need to use `useQuery` with non-serializable values, you can customize the query key hash function:
```tsx
const queryClient = new QueryClient({
defaultOptions: { queries: { queryKeyHashFn: myCustomQueryKeyHashFn } }
});
```
--create-api-client-fn option}>
Using the `--create-api-client-fn` option allows you to customize the API client creation function with specific parameters.
You can specify which services and callback functions should be included in the client by default.
> 💡 When generating multiple API client functions with different parameters, it might be more convenient to use a configuration file
> instead of command-line parameters. See the [Redocly configuration documentation](../codegen/cli/redocly-config.mdx#generating-multiple-api-client-functions)
> for more details on how to configure multiple _create API client functions_ in a YAML file.
#### Example 1: All services but no callbacks by default
_Generate a client with **all services** but **no callbacks** by default_
```bash
--create-api-client-fn createServicesOnlyClient services:all callbacks:none
```
```tsx title="src/ServicesOnlyClient.tsx"
import { createServicesOnlyClient } from './api/create-services-only-client';
import { requestFn } from '@openapi-qraft/react';
import { useQuery } from '@openapi-qraft/react/callbacks';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
// Create a client with all services but we need to explicitly specify which callbacks to use
const api = createServicesOnlyClient(
{
requestFn,
queryClient,
baseUrl: 'https://api.example.com/v1',
},
// All services are available by default
// We only need to specify the callbacks we want to use
{
// 1️⃣ Specify which callbacks we want to include
useQuery,
}
});
function UserProfile() {
// We can use the useQuery hook because we explicitly enabled it
const { data, error, isPending } =
api.users.getUserById.useQuery({
path: { userId: "123" },
});
if (isPending) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>User name: {data?.name}</div>;
}
```
#### Example 2: Specific callbacks but no services by default
_Generate a client with **specific callbacks** but **no services** by default_
```bash
--create-api-client-fn createCallbacksOnlyClient services:none callbacks:useQuery,useMutation
```
```tsx title="src/CallbacksOnlyClient.tsx"
import { createCallbacksOnlyClient } from './api/create-callbacks-only-client';
import { users } from './api/services/Users'; // Import only needed service (‼️)
import { requestFn } from '@openapi-qraft/react';
import { useSuspenseQuery } from '@openapi-qraft/react/callbacks';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
// Create a client with useQuery and useMutation callbacks but we need to explicitly specify which services to use
const usersAPI = createCallbacksOnlyClient(
// 1️⃣ Specify which service (‼️) we want to include
users,
{
requestFn,
queryClient,
baseUrl: 'https://api.example.com/v1',
},
// 2️⃣ Specify which callbacks we want to include
// ✔︎ useQuery and useMutation callbacks are already included by default
{
useSuspenseQuery,
}
);
function UserProfile() {
// 💡 We can use the useQuery hook as it's included by default
const { data, error, isPending } =
usersAPI.getUserById.useQuery({
path: { userId: "123" },
});
// 💎 We can also use the useSuspenseQuery hook because we explicitly enabled it
const { data: allUsers } = usersAPI.allUserList.useSuspenseQuery();
if (isPending) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<>
<div>User name: {data?.name}</div>
<h4>All users:</h4>
<ul>{allUsers.map(user => <li key={user.id}>{user.name}</li>)}</ul>
</>
);
}
```
#### Example 3: Minimal API client (no services, no callbacks by default)
_Generate a completely minimal client with **nothing included** by default_
```bash
--create-api-client-fn createMinimalAPIClient services:none callbacks:none
```
```tsx title="src/MinimalApiClient.tsx"
import { createMinimalAPIClient } from './api/create-minimal-api-client';
import { requestFn } from '@openapi-qraft/react';
import { getUserById } from './api/services/Users'; // Import only needed operation (❗)
import { useQuery } from '@openapi-qraft/react/callbacks';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
// Create a minimal client by explicitly specifying only the necessary operation (❗) and callbacks
const getUserByIdAPI = createMinimalAPIClient(
// 1️⃣ Explicitly specify which operation(❗) or service(‼️) we need
getUserById, // You could also use `users`, `{ users, files }`.
{
requestFn,
queryClient,
baseUrl: 'https://api.example.com/v1',
},
// 2️⃣ Explicitly specify which callbacks we need
{
useQuery,
}
});
function UserProfile() {
const { data, error, isPending } =
getUserByIdAPI.useQuery({
path: { userId: "123" },
});
if (isPending) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>User name: {data?.name}</div>;
}
```