What is Relay?
Relay is a JavaScript framework for fetching and updating GraphQL data in React. This is achieved by declaring the data requirements on a per-component basis while Relay takes care of optimising data fetching and performance. Relay provides a neat API for data management using custom React hooks, such as useQueryLoader for fetching data and useFragment for building imperative requests.
Using Relay
At Tines, we use Relay to fetch and mutate data throughout the product. Our area of focus here will be the Tines Storyboard.
This gigantic React component is the "bread-and-butter" of the application and using Relay loads a substantial amount of data.
The query can be broken down into three main chunks: fetching the "Story", "Story Runs", and "Form".
Using the useFragment
hook in each sub-component, we define the data required before neatly bundling it all together in a parent query using useLazyLoadQuery
. When we then navigate to the Storyboard in the product, Relay automatically fires a request to the backend server and populates the components with data once ALL OF IT arrives (despite only needing one of the three storyboard data chunks at any one time). While the component is suspended, a loading indicator is displayed.
export default function Story({ storyId }: Props) {
// Fetch request is made as soon as the component begins to render
const data = useLazyLoadQuery<storyBoardQuery>(
graphql`
query storyBoardQuery($id: ID!) {
story(id: $id) {
...form_query
...diagram_query
...storyRuns_query
}
}
`,
{ id: storyId }
);
return (
<Suspense fallback={<LoadingIndicator />}>
{/* <StoryBoardContent /> contains:
- <Diagram />
- <StoryRuns />
- <Form />
*/}
<StoryBoardContent data={data} />
</Suspense>
);
}
Despite the big strides Relay makes towards optimising the data fetch, the query takes a substantial amount of time to retrieve the data from the backend, and we are forced to show a loading indicator for a significant amount of time. We are also warned by Relay of "waterfalling round trips" that likely contribute to the duration of the query. Given the importance of this component, a lengthy wait time just to view the story simply will not cut it!