Skip to content

Commit c4f727c

Browse files
committed
Add section in Suspense docs for useLoadableQuery
1 parent 491ec41 commit c4f727c

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

docs/source/data/suspense.mdx

+53
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,59 @@ When the network request for `GET_DOG_QUERY` completes, the `Dog` component unsu
433433

434434
The `useBackgroundQuery` hook used in a parent component is responsible for kicking off fetches, but doesn't deal with reading or rendering data. This is delegated to the `useReadQuery` hook used in a child component. This separation of concerns provides a nice performance benefit because cache updates are observed by `useReadQuery` and re-render only the child component. You may find this as a useful tool to optimize your component structure to avoid unnecessarily re-rendering parent components when cache data changes.
435435

436+
<MinVersion version="3.9.0">
437+
438+
### Querying in response to user interaction
439+
440+
</MinVersion>
441+
442+
`useSuspenseQuery` and `useBackgroundQuery` are useful hooks that will begin loading data as soon as the hook is mounted. But what happens when you'd like to start loading your query in response to a user interaction? With `useSuspenseQuery` and `useBackgroundQuery`, you'd need to update React state in response to the user interaction in order to re-render your component.
443+
444+
Starting with Apollo Client `3.9.0`, you can use `useLoadableQuery` to start loading data in response to user interaction. This is not only more ergonomic, but starts loading the query immediately, providing a nice performance benefit.
445+
446+
`useLoadableQuery` returns a function that when called will begin fetching the query with the provided variables. Like `useBackgroundQuery`, you get access to a `queryRef` that is passed to `useReadQuery` to read the data in a child component. When the child component renders before the query has finished loading, the child component suspends.
447+
448+
Let's update our example to start loading the dog's details as a result of selecting from a dropdown.
449+
450+
```tsx
451+
function App() {
452+
const { data } = useSuspenseQuery(GET_DOGS_QUERY);
453+
const [queryRef, loadDog] = useLoadableQuery(GET_DOG_QUERY)
454+
455+
return (
456+
<>
457+
<select
458+
onChange={(e) => loadDog({ id: e.target.value })}
459+
>
460+
{data.dogs.map(({ id, name }) => (
461+
<option key={id} value={id}>
462+
{name}
463+
</option>
464+
))}
465+
</select>
466+
<Suspense fallback={<div>Loading...</div>}>
467+
{queryRef && <Dog queryRef={queryRef} />}
468+
</Suspense>
469+
</>
470+
);
471+
}
472+
473+
function Dog({ queryRef }) {
474+
const { data } = useReadQuery(queryRef)
475+
476+
return (
477+
<>
478+
<div>Name: {data.dog.name}</div>
479+
<div>Breed: {data.dog.breed}</div>
480+
</>
481+
);
482+
}
483+
```
484+
485+
> It's important to note that the `queryRef` is `null` until the query loading function is called for the first time. You should conditionally render the child component when the query has not yet been loaded.
486+
487+
We begin fetching our `GET_DOG_QUERY` as soon as a new dog is selected rather than waiting for our `Dog` component to re-render. When the `Dog` component renders, it reads data from the `GET_DOG_QUERY`, and if not ready, will suspend. As a result of this change, we've also removed the need to track the selected dog ID as part of React state!
488+
436489
### Refetching and pagination
437490

438491
Apollo's Suspense data fetching hooks return functions for refetching query data via the `refetch` function, and fetching additional pages of data via the `fetchMore` function.

0 commit comments

Comments
 (0)