This is the data fetching and caching library with zustand
npm install react-zustand-queryuseQuery, useMutation, useInfiniteQuery
bash
npm install react-zustand-query
`
or
`bash
yarn add react-zustand-query
`
Usage
$3
`typescript
import { QueryClient } from "react-zustand-query";
// Create a query client instance (optional, only if you want to manage cache directly)
const queryClient = new QueryClient();
// Access query state by key
const userQueryState = queryClient.getState("user");
`
$3
`typescript
import { useQuery } from "react-zustand-query";
function fetchUser() {
return fetch("https://jsonplaceholder.typicode.com/users/1").then((res) =>
res.json()
);
}
const { data, isLoading, error } = useQuery({
queryKey: "user",
queryFn: fetchUser,
});
`
$3
`typescript
import { useMutation } from "react-zustand-query";
function addTodo(newTodo) {
return fetch("/api/todos", {
method: "POST",
body: JSON.stringify(newTodo),
headers: { "Content-Type": "application/json" },
}).then((res) => res.json());
}
const { mutate, data, error, isLoading } = useMutation({
mutationFn: addTodo,
onSuccess: () => {
// handle success
},
onError: () => {
// handle error
},
});
// Usage in a component:
// mutate({ title: "New Todo" });
`
$3
`typescript
import { useInfiniteQuery } from "react-zustand-query";
function fetchPosts({ pageParam = 0 }) {
return fetch(/api/posts?page=${pageParam}&limit=10).then((res) =>
res.json()
);
}
const {
data,
isLoading,
error,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ["posts"],
queryFn: fetchPosts,
getNextPageParam: (lastPage, allPages, lastPageParam) => {
// Return null/undefined to indicate no more pages
return lastPage.hasMore ? lastPageParam + 1 : null;
},
initialPageParam: 0,
});
// Access the data
const allPosts = data?.pages.flatMap((page) => page.posts) ?? [];
// In your component:
return (
{allPosts.map((post) => (
{post.title}
))}
{hasNextPage && (
)}
);
`
API Reference
$3
`typescript
const { data, isLoading, error, refetch } = useQuery({
queryKey: ["users", userId],
queryFn: fetchUser,
enabled: boolean,
staleTime: number,
retry: boolean | number,
});
`
- queryKey: Unique key for the query (string or array)
- queryFn: Function that returns a promise (fetcher)
- enabled: (optional) Enable/disable the query
- staleTime: (optional) Time in ms before data is considered stale
- retry: (optional) Number of retry attempts or boolean
$3
`typescript
const { mutate, isLoading, error, data } = useMutation({
mutationFn: addTodo,
onSuccess?: (data) => void,
onError?: (error) => void,
retry?: boolean | number
});
`
- mutationFn: Function that performs the mutation (returns a promise)
- onSuccess: (optional) Callback on successful mutation
- onError: (optional) Callback on mutation error
- retry: (optional) Number of retry attempts or boolean
$3
`typescript
const {
data,
isLoading,
error,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ["posts"],
queryFn: fetchPostPage,
getNextPageParam: (lastPage, allPages, lastPageParam) => lastPage.nextCursor,
initialPageParam: 0,
});
`
- queryKey: Unique key for the query
- queryFn: Function that fetches a page of data
- getNextPageParam: (optional) Function to determine the next page parameter
- initialPageParam: (optional) Initial page parameter value
- Returns paginated data and utilities for infinite scrolling
$3
- .getState(queryKey): Get the state of a specific query
- .invalidateQueries(queryKey)`: Invalidate and refetch queries