Created by Robert Balicki & Juan Tejada, the Relay Team at Facebook recently released a new set of APIs, called Relay Hooks, for better fetching and management of GraphQL data.
React-hooks-based APIs enable developers to fetch and manage GraphQL data in React applications by leveraging the Relay framework.
Relay is a structured and opinionated JavaScript framework used to build data-driven React applications backed by GraphQL.
Basically, the Relay hooks use React.js with Relay and improve the existing container-based APIs. These relay hook-APIs provide an upper hand for developers while working with graphql data and come in handy to simplify the development process which would otherwise take a lot of extra time and code. The hooks APIs conveniently reduce the code amount by doing the same job within fewer lines of code.
Relay hooks include APIs for multiple purposes such as pagination, fetching queries, loading data with fragments, mutations, re-fetching, and subscriptions.
These newly updated hooks-based APIs are fully compatible with the existing APIs. You can easily migrate the existing containers to the new APIs if you want but you don’t need to as the container code wo
Although the hooks-based APIs are new but not untested. In fact, the Facebook website was rewritten from scratch with Relay Hooks. The APIs were written in close association with team React bearing the future of React.js in mind. However, Relay still has a long way to go to become as easygoing and popular as we would like but this new release has greatly improved the relay developer experience.
Relay Hooks are convenient to use and offer sizable advantages and features, namely-
When team Relay released its newest version earlier in March 2021, they introduced a new set of developer-friendly APIs in it.
Let’s first set up the latest version of Relay and then we’ll see how these APIs work.
First of all, you need to make sure that you have installed the newest versions of Relay and React on your device as given below-
yarn add react react-dom react-relay
Now, you can either import Relay Hooks from react-relay module or from react-relay/hooks.
import {graphql, useFragment} from ‘react-relay’; // or ‘react-relay/hooks’// …
Now, let’s understand the basics of each Relay Hook API-
This component sets a Relay environment to use in React context for the entire application. The environment prop specified by this provider component is later used by other hooks like useLazyLoadQuery or useFragment.
import { RelayEnvironmentProvider } from 'relay-hooks';
ReactDOM.render(
<RelayEnvironmentProvider environment={modernEnvironment}>
<AppTodo/>
</RelayEnvironmentProvider>,
rootElement,
);
This hook uses suspense and facilitates GraphQL query fetching during render.
import { useLazyLoadQuery } from "react-relay/hooks";
useLazyLoadQuery(query, variables, options);
It does not take environment as an argument and reads the environment set in the context instead. It takes three arguments, as given here-
It passes the specified query using graphql template literal.
It contains variable values required to fetch the query.
It contains the following options objects (optional).
The useLazyLoadQuery returns a single data object which contains the query data.
If a network request has been made, the useLazyLoadQuery can suspend the ongoing fetching operation and use Suspense for loading states.
For those who are not familiar with React Suspense, it is a new component that’s been added to the latest version of React. It’s not ready yet and still in the experimental phase. This feature allows you to suspend the ongoing operation and lets your components ‘wait’, for the data to be fetched or an asynchronous task to complete, before rendering.
The useQuery hook is used for data fetching and is similar to useLazyLoadQuery except for one thing- it does not use React Suspense.
It enables you to use the hooks without having to migrate your application to the concurrent mode. Like useLazyLoadQuery, it accepts three arguments, i.e., query, variables, and options.
This relay hook follows and implements the ‘render-as-you-fetch’ pattern (using Suspense) and accesses data fetched by loadQuery or useQueryLoader.
The pattern follows the given steps-
The usePreloadedQuery takes the following two arguments-
· query- Specifies the Graphql query template literal.
· preloadedQueryReference- Contains the query reference attained from useQueryLoader or returned by loadQuery.
The usePreloadedQuery returns a data object which contains data read out from the relay store.
This hook loads and retains queries easily and securely. It is designed to work in conjunction with the usePreloadedQuery to implement the ‘render-as-you-fetch’ pattern. It stores the query reference in state form.
It takes an initialQueryRef argument, besides the query argument, which contains an initial PreloadedQuery that is to be dispatched as the initial value of the queryReference, returned by useQueryLoader.
It returns a tuple value containing-
The loadQuery callback returns query references. However, it is not the most convenient way as it leaks this data to the Relay store unless a .dispose() function called on it.
The return value is highly unstable, therefore, you should try passing the result of a loadQuery() to usePreloadedQuery instead which makes sure that the query reference is disposed of.
It fetches data if passed a query, or both data and query if passed a preloaded request. Both the data and query will be stored inside the relay store.
loadQuery works alongside with usePreloadedQuery to implement the ‘return-as-you-fetch’ pattern (as mentioned earlier). It takes an additional fifth argument called environmentProviderOptions other than the usual ones, i.e., environment, query, variables, and options. The environmentProviderOptions provides options to pass to an environmentProvider.
It declares specifications of the data requirements of components needed for rendering and then Relay makes sure that this data gets there.
The useFragment is designed in such a way that it automatically updates the fragment data. For instance, if this data gets updated for a particular user in any way anywhere in the app, the component will re-render with this newly updated data.
It takes two arguments, i.e.,
The return value is a data object, specifying which data was read from the store.
The usePaginationFragment renders a fragment using a @connection and paginate over it.
import { usePaginationFragment } from 'relay-hooks';
This is not the end! I’ve covered most of the hooks-APIs but there are a few others that I’ve left, you can check them here.
You can use these Relay Hooks incrementally, which means you can use them for the new code or can migrate some parts of your app as well and it won’t affect the rest of your application.
Hope you found this blog helpful! Don’t leave the page without clapping🙃.
Thanks for reading!