Skip to content

Instantly share code, notes, and snippets.

@jerelmiller
Last active February 23, 2023 04:30
Show Gist options
  • Save jerelmiller/dcc53175ded52aafd623813ccd3d42fc to your computer and use it in GitHub Desktop.
Save jerelmiller/dcc53175ded52aafd623813ccd3d42fc to your computer and use it in GitHub Desktop.
Apollo Client Suspense
// Our encouraged use of suspense in Apollo will comprise of 2 hooks: useBackgroundQuery and useReadQuery (final names TBD).
// Using these 2 together encourage the use of the render-as-you-fetch pattern to start fetching as soon as possible:
// https://17.reactjs.org/docs/concurrent-mode-suspense.html#approach-3-render-as-you-fetch-using-suspense
const Parent = () => {
// This hook provides no access to data. It's meant purely as a fetching mechanism
const { promise } = useBackgroundQuery(QUERY);
return (
<Suspense fallback="Loading...">
<Child promise={promise} />
</Suspense>
);
}
const Child = ({ promise }) => {
// Suspends when the promise is pending. Handles reactive cache updates
const { data } = useReadQuery({ promise });
return <div>{data.me.fullName}</div>
}
// This also enables the ability to fetch 2 queries in parallel
const MyComponent = () => {
// Kick off both requests simultaneously
const { promise: promise1 } = useBackgroundQuery(QUERY_1);
const { promise: promise2 } = useBackgroundQuery(QUERY_2);
const { data: data1 } = useReadQuery({ promise: promise1 });
const { data: data2 } = useReadQuery({ promise: promise2 });
}
// If we can pull it off, our goal is to allow other parts of Apollo to work in conjunction with `useReadQuery` as well.
// Some examples:
// ------------------
// With useLazyQuery
// ------------------
const Parent = () => {
const [promise, setPromise] = useState();
const [fetchQuery] = useLazyQuery(QUERY);
return (
<div>
<button onClick={() => setPromise(fetchQuery())}>Fetch</button>
{promise && <Child promise={promise} />}
</div>
);
}
const Child = ({ promise }) => {
const { data } = useReadQuery({ promise });
return <div>{data.me.fullName}</div>
}
// ------------------
// With client.query()
// ------------------
// Kick off the query when the bundle is executed rather than waiting for the component to mount
const promise = client.query(QUERY)
const App = () => {
return (
<Suspense fallback="Loading...">
<MyComponent />
</Suspense>
);
}
const MyComponent = () => {
const { data } = useReadQuery({ promise });
return <div>{data.me.fullName}</div>
}
// For one-off queries, you can use useSuspenseQuery which won't execute the query until the component has rendered
const MyComponent = () => {
const { data } = useSuspenseQuery(QUERY);
return <div>{data.me.fullName}</div>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment