React Query
Learn how to use CallApi with React Query
This guide covers essential patterns and best practices for using CallApi with React Query, combining CallApi's features with React Query's caching and synchronization capabilities.
Quick Start
By default, CallApi returns errors as values in the result object instead of throwing them, which is great for explicit error handling. However, React Query expects query functions to either return data on success or throw an error on failure.
To make CallApi work seamlessly with React Query, configure it to throw errors and return only the data:
import { useQuery } from "@tanstack/react-query";
import { callApi } from "@zayne-labs/callapi";
type Todo = {
completed: boolean;
id: number;
title: string;
};
export const useTodos = () => {
return useQuery({
queryKey: ["todos"],
queryFn: () => {
return callApi<Todo[], false>("/todos", {
throwOnError: true,
resultMode: "onlyData",
});
},
});
};Configuration Options
Key options for React Query integration:
throwOnError: true- Makes CallApi throw errors instead of returning themresultMode: "onlyData"- Returns just the data property, perfect for React Query
These settings ensure CallApi behaves exactly like React Query expects: throwing errors for failures and returning clean data for successes.
Centralized Configuration
import { createFetchClient } from "@zayne-labs/callapi";
export const callApiForQuery = createFetchClient({
baseURL: "https://api.example.com",
// Default to React Query compatible settings
throwOnError: true,
resultMode: "onlyData",
});
// Use the configured client in queries
export const useTodos = () => {
return useQuery({
queryKey: ["todos"],
queryFn: () => callApiForQuery<Todo[]>("/todos"),
});
};Data Inference via typescript
Option 1: Schema Validation (Recommended)
Using validation libraries like Zod provides both runtime safety and automatic type inference:
import { useQuery } from "@tanstack/react-query";
import { callApi } from "@zayne-labs/callapi";
import { z } from "zod";
const todosSchema = z.array(
z.object({
id: z.number(),
title: z.string(),
completed: z.boolean(),
})
);
export const useTodos = () => {
return useQuery({
queryKey: ["todos"],
queryFn: () => {
return callApi("/todos", {
schema: { data: todosSchema },
throwOnError: true,
resultMode: "onlyData",
});
},
});
};Option 2: Manual Type Specification
import { useQuery } from "@tanstack/react-query";
import { callApi } from "@zayne-labs/callapi";
type Todo = {
completed: boolean;
id: number;
title: string;
};
export const useTodos = () => {
return useQuery({
queryKey: ["todos"],
queryFn: () => {
// Pass `false` as second generic to signal errors will be thrown allow callApi to return the expected type
// This is needed due to TypeScript limitations with partial generic inference
// See: https://github.com/microsoft/TypeScript/issues/26242
return callApi<Todo[], false>("@get/todos", {
throwOnError: true,
resultMode: "onlyData",
});
},
});
};Last updated on