React Query
redmine-api-client-react, TanStack Query options and hooks for the Redmine client.
redmine-api-client-react provides queries for TanStack Query, one module per resource, and hooks for paged lists.
Installation
pnpm add redmine-api-client redmine-api-client-react @tanstack/react-queryIt works with React 18 and 19, and TanStack Query 5.
Setup
Provide the client
Wrap your app in a QueryClientProvider and a RedmineClientProvider:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RedmineClient } from "redmine-api-client";
import { RedmineClientProvider } from "redmine-api-client-react";
const queryClient = new QueryClient();
const redmine = new RedmineClient("https://redmine.example.com", { key: apiKey });
export function Root() {
return (
<QueryClientProvider client={queryClient}>
<RedmineClientProvider client={redmine}>
<App />
</RedmineClientProvider>
</QueryClientProvider>
);
}Query
Get the client with useRedmineClient() and pass a query to useQuery:
import { useQuery } from "@tanstack/react-query";
import { redmineIssueQuery, useRedmineClient } from "redmine-api-client-react";
export function Issue({ id }: { id: number }) {
const client = useRedmineClient();
const { data: issue, isPending } = useQuery(redmineIssueQuery(client, id));
if (isPending) return <p>Loading…</p>;
return <h1>{issue?.subject}</h1>;
}Invalidate after changes
Each resource has a filter that matches all of its queries:
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { redmineIssuesQueries, useRedmineClient } from "redmine-api-client-react";
const client = useRedmineClient();
const queryClient = useQueryClient();
const closeIssue = useMutation({
mutationFn: (id: number) => client.issuesClient.updateIssue(id, { issue: { statusId: 5 } }),
onSuccess: () => queryClient.invalidateQueries(redmineIssuesQueries),
});Why queries, not hooks?
The queries are plain TanStack Query options, so they work with useQuery, useSuspenseQuery, prefetchQuery, ensureQueryData and getQueryData, e.g. in a router loader:
await queryClient.ensureQueryData(redmineProjectQuery(client, "my-project"));