Last active
February 23, 2023 04:30
-
-
Save jerelmiller/dcc53175ded52aafd623813ccd3d42fc to your computer and use it in GitHub Desktop.
Apollo Client Suspense
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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