Retrieve and Display Data with GraphQL Queries in Next.js using urql

Thomas Greco
InstructorThomas Greco
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 5 years ago

Urql is a library focused on providing ReactJS users with easy access to GraphQL APIs. In this video, we learn how to connect components within a Next.js application. We take a look at using Urql's <Connect /> component and we'll also check out different ways that we can use the library's query(), QueryObject creator. By the end, you'll know how to set up GraphQL queries in any ReactJS application!

Demo Site Urql GitHub

Instructor: [00:01] To begin using URQL, we're going to need to grab the provider and client features from the URQL library. The first thing we're going to do here is set up the client constructor. We're going to want to specify a URL value, which would just be the GraphQL API that we're going to be trying to get data from.

[00:22] Once our client's set up, we can go ahead and wrap our component in the provider component. We're also going to need to specify the client property here, and we're just going to give it the value of client as it relates to the client variable up top.

[00:39] Inside of our iteratePokemon file, we're just going to grab query and connect from URQL. The first thing I'm going to do here is define a query, allPokemonQuery. I'm just going to use that query function we imported above.

[00:58] Inside here, we're going to pass in our query string. We're going to have a variable first, which is going to be used for our Pokémon's query. From that, we're just going to say that we want the ID and name of each Pokémon we receive.

[01:15] Following this, I just want to pass in a variable. As we know, this is taking the first argument. By setting first to five, we'll just get the first five items that we get back. Now, our query's set up, so we could use it inside of our connect component.

[01:33] The connect component's going to have a query prop, which we're going to pass in allPokemonQuery to. Then inside of the children prop, it's going to give us the data back in that data argument. The loaded argument is going to give us a Boolean value, which will allow us to just easily display a loading indicator.

[01:53] It's going to turn to true when our data resolves. Over here, we're just going to display a div. As we know, the data's coming back as data.pokemons. We can just map over this data, and create a button for each Pokémon we get back.

[02:13] In each button, we're just going want to specify a key. We'll just set that to the ID we get back. Then inside of our button, we shouldn't give a second level header. We'll display the name.

[02:31] Now, if we take a look at the app, we see these buttons are rendering, and they've got the names of the first five Pokémon we've gotten back. Now, let's just create a component that displays the individual properties of each Pokémon.

[02:46] Again, we're going to need to import the connect component, as well as the query function, from URQL. I'm also going to import some predefined style objects I have here.

[03:02] Now that I have everything imported, I'm just going to create a query string constant. This query is going to take the ID as an argument. From this, we just want to get back the ID, name, image URL, as well as the max and min heights of each Pokémon.

[03:30] Below our query string, I'm just going to define a function, createQuery, which is just going to take in an ID, and then query our GraphQL API, using this ID, in addition to the query string constant we just defined above.

[03:50] Now that our query's set up, let's define this Pokémon component. It's going to take an ID. We're going to jump right in, and use the connect component from URQL. Now, again, we're defining that query prop, we're just using the createQuery function, and passing in the ID that this component's receiving.

[04:13] Below our query, we're going to define our children again. In here, we're going to specify the loaded and data arguments. In our function body, I'm going to return a div. Now, again, we're saying that if loaded equals false, just show this loading indicator.

[04:37] Otherwise, we're going to want to do something with our data. Since our data's being received as an object, we'll be able to plug right into it. Say that I want to display the name of each Pokémon, and I'm also going to render the max and minimum height inside these h4 tags.

[05:08] The final thing I'm going to do is just use an image tag to render the image URL we're getting back from our API. That looks pretty good. Now, we're going to want to export this. Now, I'll be able to grab this in my iteratePokemon file.

[05:25] Now, inside here, I'm just going to import our component. Before I actually embed this import within our component, I'm quickly going to define some default state. Here, we're just giving this selected state a default ID value.

[05:44] Below my state, I'm going to define a selectPokemon method, which is going to take in an ID. This is going to set the state of selected to whatever the ID being passed in is. Now that that's ready to go, I'm going to add an onClick handler to our styled button.

[06:10] Every time this onClick event is fired, it's going to update the ID according to that selectPokemon method we just defined. Lastly, we're going to add in that Pokémon component. As we know, this takes an ID. We're going to set ID equal to this.state.selected. Pretty straightforward.

[06:39] Now, if we refresh our page, boom. Our buttons are rendering for us. As we click on them, that Pokémon component to the right is updating depending on the ID value that gets passed in.

~ just now

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today