React
Zero has built-in support for React. Here’s what basic usage looks like:
import {useQuery, useZero} from '@rocicorp/zero/react';
import {type Schema} from './schema.ts';
import {type Mutators} from './mutators.ts';
function IssueList() {
const z = useZero<Schema, Mutators>();
let issueQuery = z.query.issue
.related('creator')
.related('labels')
.limit(100);
const userID = selectedUserID();
if (userID) {
issueQuery = issueQuery.where('creatorID', '=', userID);
}
const [issues, issuesDetail] = useQuery(issueQuery);
return (
<>
<div>
{issuesDetail.type === 'complete' ? 'Complete' : 'Partial'}
results
</div>
<div>
{issues.map(issue => (
<IssueRow issue={issue} />
))}
</div>
</>
);
}
ZeroProvider
The useZero
hook must be used within a ZeroProvider
component. The
ZeroProvider
component is responsible for creating and destroying
Zero
instances reactively.
import {SessionProvider} from 'my-auth-provider';
import {ZeroProvider} from '@rocicorp/zero/react';
import {type Schema, schema} from './schema.ts';
import {type Mutators, createMutators} from './mutators.ts';
export function Root() {
const session = useSession();
const {userID, authToken: auth} = session;
const server = import.meta.env.VITE_PUBLIC_SERVER;
const mutators = useMemo(() => {
return createMutators(auth);
}, [auth]);
return (
// ZeroProvider will reactively create and destroy Zero instances
// as needed when props change.
<ZeroProvider {...{userID, auth, schema, mutators, server}}>
<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>
Complete quickstart here: