React SWR Integration
SWR is a React Hooks library for data fetching that provides features like caching, revalidation, and more. oRPC SWR integration is very lightweight and straightforward - there's no extra overhead.
WARNING
This documentation assumes you are already familiar with SWR. If you need a refresher, please review the official SWR documentation before proceeding.
Installation
npm install @orpc/experimental-react-swr@latestyarn add @orpc/experimental-react-swr@latestpnpm add @orpc/experimental-react-swr@latestbun add @orpc/experimental-react-swr@latestdeno add npm:@orpc/experimental-react-swr@latestWARNING
The experimental- prefix indicates that this integration is still in development and may change in the future.
Setup
Before you begin, ensure you have already configured a server-side client or a client-side client.
import { createSWRUtils } from '@orpc/experimental-react-swr'
export const orpc = createSWRUtils(client)
orpc.planet.find.key({ input: { id: 123 } })
//
//
//
//Avoiding Key Conflicts?
You can easily avoid key conflicts by passing a unique base key when creating your utils:
const userORPC = createSWRUtils(userClient, {
path: ['user']
})
const postORPC = createSWRUtils(postClient, {
path: ['post']
})Data Fetching
Use .key and .fetcher methods to configure useSWR for data fetching:
import useSWR from 'swr'
const { data, error, isLoading } = useSWR(
orpc.planet.find.key({ input: { id: 123 } }),
orpc.planet.find.fetcher({ context: { cache: true } }), // Provide client context if needed
)Infinite Queries
Use .key and .fetcher methods to configure useSWRInfinite for infinite queries:
import useSWRInfinite from 'swr/infinite'
const { data, error, isLoading, size, setSize } = useSWRInfinite(
(index, previousPageData) => {
if (previousPageData && !previousPageData.nextCursor) {
return null // reached the end
}
return orpc.planet.list.key({ input: { cursor: previousPageData?.nextCursor } })
},
orpc.planet.list.fetcher({ context: { cache: true } }), // Provide client context if needed
)Subscriptions
Use .key and .subscriber methods to configure useSWRSubscription to subscribe to an Event Iterator:
import useSWRSubscription from 'swr/subscription'
const { data, error } = useSWRSubscription(
orpc.streamed.key({ input: { id: 3 } }),
orpc.streamed.subscriber({ context: { cache: true }, maxChunks: 10 }), // Provide client context if needed
)Use .liveSubscriber to subscribe to the latest events without chunking:
import useSWRSubscription from 'swr/subscription'
const { data, error } = useSWRSubscription(
orpc.streamed.key({ input: { id: 3 } }),
orpc.streamed.liveSubscriber({ context: { cache: true } }), // Provide client context if needed
)Mutations
Use .key and .mutator methods to configure useSWRMutation for mutations with automatic revalidation on success:
import useSWRMutation from 'swr/mutation'
const { trigger, isMutating } = useSWRMutation(
orpc.planet.list.key(),
orpc.planet.create.mutator({ context: { cache: true } }), // Provide client context if needed
)
trigger({ name: 'New Planet' }) // auto revalidate orpc.planet.list.key() on successManual Revalidation
Use .matcher to invalidate data manually:
import { mutate } from 'swr'
mutate(orpc.matcher()) // invalidate all orpc data
mutate(orpc.planet.matcher()) // invalidate all planet data
mutate(orpc.planet.find.matcher({ input: { id: 123 }, strategy: 'exact' })) // invalidate specific planet dataCalling Clients
Use .call to call a procedure client directly. It's an alias for corresponding procedure client.
const planet = await orpc.planet.find.call({ id: 123 })Operation Context
When clients are invoked through the SWR integration, an operation context is automatically added to the client context. This context can be used to configure the request behavior, like setting the HTTP method.
import {
SWR_OPERATION_CONTEXT_SYMBOL,
SWROperationContext,
} from '@orpc/experimental-react-swr'
interface ClientContext extends SWROperationContext {
}
const GET_OPERATION_TYPE = new Set(['fetcher', 'subscriber', 'liveSubscriber'])
const link = new RPCLink<ClientContext>({
url: 'http://localhost:3000/rpc',
method: ({ context }, path) => {
const operationType = context[SWR_OPERATION_CONTEXT_SYMBOL]?.type
if (operationType && GET_OPERATION_TYPE.has(operationType)) {
return 'GET'
}
return 'POST'
},
})