React

Zero has built-in support for React. Here's what basic usage looks like.

Setup

Use the ZeroProvider component to setup Zero. It takes care of creating and destroying Zero instances reactively:

import {createRoot} from 'react-dom/client'
import {ZeroProvider} from '@rocicorp/zero/react'
import {useSession} from 'my-session-provider'
import App from './App.tsx'
import {schema} from 'schema.ts'
import {mutators} from 'mutators.ts'
 
const cacheURL = import.meta.env.VITE_PUBLIC_ZERO_CACHE_URL!
 
export default function Root() {
  const session = useSession()
  const {userID} = session
  const context = {userID}
 
  return (
    <ZeroProvider
      {...{userID, context, cacheURL, schema, mutators}}
    >
      <App />
    </ZeroProvider>
  )
}

You can also pass a Zero instance to the ZeroProvider if you want to control the lifecycle of the Zero instance yourself:

// ZeroProvider just sets up the context, it doesn't manage
// the lifecycle of the Zero instance.
<ZeroProvider zero={zero}>
  <App />
</ZeroProvider>

Usage

Use useQuery to run queries:

import {useQuery} from '@rocicorp/zero/react'
import {queries} from 'queries.ts'
 
function Posts() {
  const [posts] = useQuery(
    queries.posts.byStatus({status: 'draft'})
  )
 
  return (
    <>
      {posts.map(p => (
        <div key={p.id}>
          {p.title} ({p.comments.length} comments)
        </div>
      ))}
    </>
  )
}

Use useZero to get access to the Zero instance, for example to run mutators:

import {useZero} from '@rocicorp/zero/react'
import {mutators} from 'mutators.ts'
 
function CompleteButton({issueID}: {issueID: string}) {
  const zero = useZero()
 
  const onClick = () => {
    zero.mutate(mutators.issues.complete({id: issueID}))
  }
 
  return <button onClick={onClick}>Complete Issue</button>
}

Suspense

The useSuspenseQuery hook is exactly like useQuery, except it supports React Suspense.

const [issues] = useSuspenseQuery(issueQuery, {
  suspendUntil: 'complete' // 'partial' or 'complete'
})

Use the suspendUntil parameter to control how long to suspend for. The value complete suspends until authoritative results from the server are received. The partial value suspends until any non-empty data is received, or for a empty result that is complete.

Examples

See the sample directory for more complete React examples.