Calling procedures
Learn how to call queries and mutations in your app.
Overview
There are two ways to call procedures. In client components we use the useQuery
and useMutation
hooks to call the procedures.
On the server we use the trpc
api caller to call the procedures directly.
Client
The client uses Tanstack Query to manage data fetching and caching.
useQuery
'use client'import { api } from '#lib/trpc/react'export function ContactPage(props: {params: {id: string}}) {const { data, isLoading } = api.contacts.byId.useQuery({id,})// render the page}
useSuspenseQuery
useSuspenseQuery
is very useful as it guarantees data to be defined, so you don't have to check for isLoading
for conditional rendering.
It also enables you use Next.js streaming to render the page as soon as the data is available.
// in a server component, eg page or layoutimport { Suspense } from 'react'import { api, HydrateClient } from '#lib/trpc/rsc'import { ContactPage } from '#components/contact-page'export default async function Page(params: { id: string }) {api.contacts.byId.prefetch({id: params.id,})return (<HydrateClient><Suspense fallback={<div>Loading...</div>}><ContactPage id={params.id} /></Suspense></HydrateClient>)}
// in a client componentimport { api } from '#lib/trpc/react'export function ContactPage(props: { id: string }) {const [data] = api.contacts.byId.useSuspenseQuery({id,})return <div>{data.name}</div>}
useMutation
'use client'import { api } from '#lib/trpc/react'export default function ProfilePage() {const { user } = useAuth()const utils = api.useUtils()const mutation = api.users.updateProfile.useMutation({onSettled: () => {// Invalidate the user cache, so the updated user is refetchedutils.users.invalidate()},})return (<buttononClick={() => {mutation.mutate({name: 'John Doe',})}}>Save</button>)}
Server
To fetch and use the data on the server, you can use the caller
object.
// app/[slug]/layout.tsximport { caller } from '#lib/trpc/rsc'export default Layout(props: {children: React.ReactNodeparams: {slug: string}}) {const workspace = await caller.workspaces.bySlug({slug: props.params.slug,})if (!workspace) {notFound()}return (<div>{props.children}</div>)}
Was this helpful?