Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions contents/docs/react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,45 @@ const [issues] = useSuspenseQuery(issueQuery, {

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`.

## Query Identity

You don't need to memoize queries. Build them inline, where you use them, and pass them straight to `useQuery`.

Zero caches the queries you build with [ZQL](/docs/zql). Build the same query again and you usually get back the same `Query` object, even when it has `related()` or `whereExists()` callbacks written inline. So rebuilding a query on every render is cheap. You can also use a query as a dependency of `useEffect` or `useMemo`, or pass it as a prop to a component wrapped in `React.memo`:

```tsx
import {useEffect} from 'react'
import {useQuery} from '@rocicorp/zero/react'
import {zql} from 'schema.ts'

function IssueSearch({text}: {text: string}) {
// Rebuilt on every render. No useMemo needed.
const query = zql.issue
.where('title', 'ILIKE', `%${text}%`)
.orderBy('created', 'desc')
const [issues] = useQuery(query)

// Scroll back to the top when the search changes.
useEffect(() => {
window.scrollTo(0, 0)
}, [query])

return issues.map(issue => (
<div key={issue.id}>{issue.title}</div>
))
}
```

This example passes ZQL to `useQuery` directly, so it runs [only on the client](/docs/queries#local-only-queries).

Calls to [registered queries](/docs/queries#query-registries) work a little differently. Each call like `queries.posts.byStatus({status})` returns a new object. You can still pass it inline: `useQuery` sees that it's the same query with the same arguments and reuses its previous work. But don't use the returned object as a dependency. Use its arguments instead.

Keep in mind:

- Identity follows how you build a query. `zql.issue.where('status', 'open').where('priority', 'high')` and `zql.issue.where('priority', 'high').where('status', 'open')` return the same rows, but they can be different objects.
- A different value, such as a different ID in `where()`, gives a different object.
- Identity is an optimization, not a promise. Zero can hand back a new object for a query it has built before. When that happens, an effect or memo that depends on the query just runs again, so make sure that's safe.

## Examples

See [the sample directory](/docs/samples) for more complete React examples.
Loading