BT

Facilitating the spread of knowledge and innovation in professional software development

Contribute

Topics

Choose your language

InfoQ Homepage News Relay Hooks Released, Improves User Experience with Data Prefetching

Relay Hooks Released, Improves User Experience with Data Prefetching

This item in japanese

Bookmarks

Robert Balicki and Juan Tejada, software engineers at Facebook, recently released Relay Hooks, a set of new APIs for fetching and managing GraphQL data. Relay Hooks have been battle-tested on the Facebook.com rewrite, and are the recommended way to use Relay at Facebook.

Relay Hooks are a set of React Hooks-based APIs that strives to simplify working with GraphQL data and improve the developer experience. Relay Hooks include APIs for fetching queries, loading data with fragments, pagination, refetching, mutations, and subscriptions. According to Balicki and Tejada, Relay Hooks offer sizeable advantages: fewer lines of code and less indirection than the equivalent container-based solution; more complete Flow and Typescript coverage; automation of error-prone tasks (refetch and pagination queries); fetch policy configuration; and lower experienced latency by fetching data before a component renders.

Speculative fetching seeks to improve user experience by fetching data before it is needed. Resource hints, for instance, let developers declaratively prefetch resources. Balicki and Tejada provide another example of prefetching that leverages Relay Hooks to fetch data when a user hovers on a button. As the delay between hover and click on a button is rarely below 150ms (readers may test their click speed here), and users do not perceive latency below 100ms, fetching on hover may provide a 250ms budget for data to arrive and be displayed for an ideal user experience. The code example is as follows:

const UserQuery = graphql`
  query UserLinkQuery($userId: ID!) {
    user(id: $userId) {
      user_details_blurb
    }
  }
`;

function UserLink({ userId, userName }) {
  const [queryReference, loadQuery] = useQueryLoader(UserQuery);

  const [isPopoverVisible, setIsPopoverVisible] = useState(false);

  const maybePrefetchUserData = useCallback(() => {
    if (!queryReference) {
      // calling loadQuery will cause this component to re-render.
      // During that re-render, queryReference will be defined.
      loadQuery({ userId });
    }
  }, [queryReference, loadQuery]);

  const showPopover = useCallback(() => {
    maybePrefetchUserData();
    setIsPopoverVisible(true);
  }, [maybePrefetchUserData, setIsPopoverVisible]);

  return <>
    <Button
      onMouseOver={maybePrefetchUserData}
      onPress={showPopover}
    >
      {userName}
    </Button>
    {isPopoverVisible && queryReference && (
      <Popover>
        <React.Suspense fallback={<Glimmer />}>
          <UserPopoverContent queryRef={queryReference} />
        </React.Suspense>
      </Popover>
    )}
  </>
}

function UserPopoverContent({queryRef}) {
  // The following call will Suspend if the request for the data is still
  // in flight:
  const data = usePreloadedQuery(UserQuery, queryRef);
  // ...
}

In the previous code, maybePrefetchUserData is run on hover and triggers a network request if the query cannot be fulfilled from the local cache. Balicki and Tejada explained:

When the button is finally pressed, the user will thus see content sooner. By contrast, the [existing] container-based APIs initiate network requests when the component renders.

One developer on Reddit reported the better developer experience for pagination:

I’m so excited to play with this. The simplification of pagination is HUGE [in my opinion]

Relay Hooks are additionally fully compatible with React Strict Mode and are the recommended way to use Relay at Facebook since mid-2019. The new APIs are however fully compatible with the existing container-based APIs.


Relay
is a GraphQL client for React. Relay relies on React components locally declaring their data dependencies. Relay minimizes roundtrips by fetching the data dependencies for all the components in a single GraphQL request. Relay additionally provides APIs that support optimistic updates and synchronize components with their data dependencies.

We need your feedback

How might we improve InfoQ for you

Thank you for being an InfoQ reader.

Each year, we seek feedback from our readers to help us improve InfoQ. Would you mind spending 2 minutes to share your feedback in our short survey? Your feedback will directly help us continually evolve how we support you.

Take the Survey

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT

Is your profile up-to-date? Please take a moment to review and update.

Note: If updating/changing your email, a validation request will be sent

Company name:
Company role:
Company size:
Country/Zone:
State/Province/Region:
You will be sent an email to validate the new email address. This pop-up will close itself in a few moments.