From 80d41ca9f4bbc917f2bfd97bb3c5b4bd67c080e7 Mon Sep 17 00:00:00 2001 From: unnoq Date: Tue, 10 Dec 2024 10:50:48 +0700 Subject: [PATCH] docs --- .../content/docs/client/react-query.mdx | 172 ++++++++++++++++++ apps/content/examples/react-query.ts | 4 + apps/content/package.json | 1 + apps/content/tsconfig.json | 1 + 4 files changed, 178 insertions(+) create mode 100644 apps/content/content/docs/client/react-query.mdx create mode 100644 apps/content/examples/react-query.ts diff --git a/apps/content/content/docs/client/react-query.mdx b/apps/content/content/docs/client/react-query.mdx new file mode 100644 index 00000000..c22b7a8a --- /dev/null +++ b/apps/content/content/docs/client/react-query.mdx @@ -0,0 +1,172 @@ +--- +title: React Query +description: Simplify React Query usage with minimal integration using ORPC and TanStack Query +--- + +## Installation + +```package-install +@orpc/client @orpc/react-query @tanstack/react-query +``` + +## Setup + +### Using a Global Client + +```ts twoslash +import { createORPCReactQueryUtils } from '@orpc/react-query'; +import { createORPCClient } from '@orpc/client'; +import type { router } from 'examples/server'; + +// Create an ORPC client +export const client = createORPCClient({ + baseURL: 'http://localhost:3000/api', +}); + +// Create React Query utilities for ORPC +export const orpc = createORPCReactQueryUtils(client); + +// @noErrors +orpc.getting. +// ^| +``` + +### Using Context with a Client + +```tsx twoslash +import { createORPCReactQueryUtils, RouterUtils } from '@orpc/react-query'; +import { createORPCClient } from '@orpc/client'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import type { router } from 'examples/server'; +import * as React from 'react'; + +const ORPCContext = React.createContext | undefined>(undefined); + +export function useORPC() { + const orpc = React.useContext(ORPCContext); + + if (!orpc) { + throw new Error('ORPCContext is not available.'); + } + + return orpc; +} + +export function ORPCProvider({ children }: { children: React.ReactNode }) { + const [client] = React.useState(() => + createORPCClient({ + baseURL: 'http://localhost:3000/api', + }) + ); + const [queryClient] = React.useState(() => new QueryClient()); + + const orpc = React.useMemo(() => createORPCReactQueryUtils(client), [client]); + + return ( + + + {children} + + + ); +} + +// Example usage +const orpc = useORPC(); +// @noErrors +orpc.getting. +// ^| +``` + +## Multiple ORPC Instances + +To prevent conflicts when using multiple ORPC instances, you can provide a unique base path to `createORPCReactQueryUtils`. + +```tsx twoslash +import { createORPCReactQueryUtils } from '@orpc/react-query' + +// Create separate ORPC instances with unique base paths +const userORPC = createORPCReactQueryUtils('fake-client' as any, ['__user-api__']) +const postORPC = createORPCReactQueryUtils('fake-client' as any, ['__post-api__']) +``` + +This ensures that each instance manages its own set of query keys and avoids any conflicts. + +## Usage + +### Standard Queries and Mutations + +```ts twoslash +import { useMutation, useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query' +import { orpc } from 'examples/react-query' + +// Fetch data +const { data: gettingData } = useQuery(orpc.getting.queryOptions({ input: { name: 'unnoq' } })) + +// Use suspense query +const { data: postData } = useSuspenseQuery( + orpc.post.find.queryOptions({ input: { id: 'example' } }), +) + +// Perform mutations +const { mutate: postMutate } = useMutation(orpc.post.create.mutationOptions()) + +// Invalidate queries +const queryClient = useQueryClient() +queryClient.invalidateQueries({ queryKey: orpc.key() }) // Invalidate all queries +queryClient.invalidateQueries({ queryKey: orpc.post.find.key({ input: { id: 'example' } }) }) // Specific queries +``` + +> **Note**: This library enhances [TanStack Query](https://tanstack.com/query/latest) by managing query keys and functions for you, providing a seamless developer experience. + + +## Infinite Queries + +Infinite queries require a `cursor` in the input field for pagination. + +```tsx twoslash +import { os } from '@orpc/server'; +import { z } from 'zod'; +import { createORPCReactQueryUtils } from '@orpc/react-query'; +import { useInfiniteQuery, useSuspenseInfiniteQuery } from '@tanstack/react-query'; +import * as React from 'react'; + +const router = { + user: { + list: os + .input(z.object({ cursor: z.number(), limit: z.number() })) + .func((input) => ({ + nextCursor: input.cursor + input.limit, + users: [], // Fetch your actual data here + })), + }, +}; + +const orpc = createORPCReactQueryUtils('fake-client' as any); + +export function MyComponent() { + const query = useInfiniteQuery( + orpc.user.list.infiniteOptions({ + input: { limit: 10 }, + getNextPageParam: (lastPage) => lastPage.nextCursor, + initialPageParam: 0, + }) + ); + + const query2 = useSuspenseInfiniteQuery( + orpc.user.list.infiniteOptions({ + input: { limit: 10 }, + getNextPageParam: (lastPage) => lastPage.nextCursor, + initialPageParam: 0, + }) + ); + + return ( +
+ {query.isLoading && 'Loading...'} + {query.isSuccess &&
Data: {JSON.stringify(query.data)}
} + {query.isError &&
Error: {query.error.message}
} +
+ ); +} +``` diff --git a/apps/content/examples/react-query.ts b/apps/content/examples/react-query.ts new file mode 100644 index 00000000..d3b20b7c --- /dev/null +++ b/apps/content/examples/react-query.ts @@ -0,0 +1,4 @@ +import type { router } from 'examples/server' +import { createORPCReactQueryUtils } from '@orpc/react-query' + +export const orpc = createORPCReactQueryUtils('fake-client' as any) diff --git a/apps/content/package.json b/apps/content/package.json index 15d3eb1e..69e77b57 100644 --- a/apps/content/package.json +++ b/apps/content/package.json @@ -26,6 +26,7 @@ "@orpc/next": "workspace:*", "@orpc/openapi": "workspace:*", "@orpc/react": "workspace:*", + "@orpc/react-query": "workspace:*", "@orpc/server": "workspace:*", "@orpc/zod": "workspace:*", "@types/express": "^5.0.0", diff --git a/apps/content/tsconfig.json b/apps/content/tsconfig.json index cdb1a047..fb4c05b4 100644 --- a/apps/content/tsconfig.json +++ b/apps/content/tsconfig.json @@ -30,6 +30,7 @@ { "path": "../../packages/server" }, { "path": "../../packages/client" }, { "path": "../../packages/react" }, + { "path": "../../packages/react-query" }, { "path": "../../packages/zod" }, { "path": "../../packages/next" } ],