Queries: Loading Links

Preparing the React components

The first piece of functionality you’ll implement in the app is loading and displaying a list of Link elements. We’ll start by preparing some React components for displaying the links. Let’s begin at the bottom of the component hierarchy by writing one that’ll render a single link.

This is a simple React component that expects a link in its props and renders the link’s description and url. Easy as pie! 🍰

Note: This tutorial doesn’t focus too much on using semantic HTML elements, for the sake of simplifying parts of the steps we’ll take to create this app. The two <div>s here are later used for styling.

Next, you’ll implement the component that renders a list of links.

For now you’re pasting in some mock data to make sure the component setup works. You’ll soon replace this with some actual data loaded from the server!

Run the app to check if everything works so far! The app should now display the two links from the linksToRender array:

Run the app to ensure everything works

Writing the GraphQL query

Next you’ll load the actual links that are stored in the database from your GraphQL API. The first thing you need to do for that is define the GraphQL query you want to send.

Here is what it looks like:

{
  feed {
    links {
      id
      createdAt
      description
      url
    }
  }
}

You could now simply execute this query in a Playground (against the application schema) and retrieve the results from your GraphQL server. But let’s see how to run this query in your React app with urql!

Queries with urql

When using urql, you’ve got several ways of sending queries to the server. The React bindings for urql call methods on the Client that return a “stream” of results. These low-level methods are called executeQuery, executeMutation, and executeSubscription. The returned stream of results is implemented using the Wonka library, which you can read more about on its site.

A practical example of using these is a little longer than using the React bindings, but would look as follows:

import { createRequest } from 'urql'
import { pipe, subscribe } from 'wonka'

const request = createRequest(gql`
  {
    feed {
      links {
        id
      }
    }
  }
`, {
  // ... variables
});

pipe(
  client.executeQuery(request),
  subscribe(response => {
    console.log(response.data.feed);
  })
);

Note: urql is planned to expose helper methods on its Client that internally call useRequest for you eventually, but since it is primarily meant to be used with its React bindings, these methods haven’t been implemented yet. Stay tuned!

The more declarative way when using React however is to use urql’s hook APIs to manage your GraphQL data just using components.

Depending on whether you’re using queries, mutations, or subscriptions there are three corresponding hooks: useQuery, useMutation, and useSubscription. All three also have corresponding components with render prop APIs.

These hooks and components are convenient wrappers around the urql Client! They automatically take care of cancellation, updates, and correctly set the initial state for you.

When it comes to making a GraphQL query using the urql hooks, you will need to pass your query as an option to useQuery and optionally pass some variables as well. The hook will internally tell the client to execute your query, and the cache will be able to proactively send updates to your components, when the data changes or the cached data is invalidated.

In general, the process for you to add some data fetching logic will be very similar every time:

  1. write the query as a JavaScript constant using the gql parser function
  2. use the useQuery hook passing the GraphQL query and variables as { query, variables }
  3. access the query results that the hook returns, const [result] = useQuery(...)

What’s going on here?

  1. First, you create a JavaScript constant called FEED_QUERY that holds your GraphQL query. The gql function parses the plain string that contains the GraphQL code (if you’re unfamiliar with the backtick-syntax, you can read up on JavaScript’s tagged template literals).
  2. Finally, you add the useQuery hook to the component, passing FEED_QUERY to the query option.

Note: Notice that the example still returns the mocked linksToRender as a function result, as you haven’t written any code just yet to use the result from useQuery.

Awesome, that’s all your data fetching code. If you check your app now you can see that a request is sent to your GraphQL API. But as you can already tell, LinkList is not using the server data yet, so let’s make it happen 🤩

You can now finally remove the mock data and render actual links that are fetched from the server.

Let’s walk through what’s happening in this code. As expected, useQuery returns an array with the result as the first item. It returns this array because the second value of any hook that urql exposes is always an execute function that can be used to refetch queries.

The properties of the result from the hook tell us more about the state of your query and pass you the data that it receives from your GraphQL API:

  1. fetching: Is true as long as the request is still ongoing and the response hasn’t been received, otherwise it’ll be false
  2. error: In case the request fails, this field will contain a CombinedError that tells you what exactly went wrong. Depending on what error has occured it’ll either have a networkError or a graphQLErrors property.
  3. data: This is the actual data that is received from the server. It’ll have a links property with a list of Link elements, since the FEED_QUERY definition is requesting them.

That’s it! You should see the exact same screen as before! 🤩 And to summarize, in this section you’ve:

  • created a Link and LinkList
  • added a useQuery hook to load some feed data from your GraphQL API

Note: If the browser on http://localhost:4000 only says error and is empty otherwise, you probably forgot to have your server running. Note that for the app to work the server needs to run as well - so you have two running processes in your terminal: One for the server and one for the React app. To start the server, navigate into the server directory and run yarn start.

Unlock the next chapter
What's the declarative way for running GraphQL queries with React & urql?
Using a higher-order component called 'graphql'
Using the 'useQuery' hook
Using 'fetch' and putting the query in the body of the request
Using XMLHTTPRequest and putting the query in the body of the request