Make HTTP Requests with React

Kent C. Dodds
InstructorKent C. Dodds

Share this video with your friends

Send Tweet

Most useful React applications involve interacting with a server to load and persist data. To do this on the web, we use HTTP requests with the browser’s built-in fetch API (or you may use some other open source library that’s built on top of this API). HTTP requests like this are inherently asynchronous in nature and they’re also side-effects so we’ll need to manage not only starting the request, but also what we should show the user while the request is “in flight.”

In this lesson we’ll use a public GraphQL server that serves up pokemon data to load information for a given pokemon name. We’ll learn how to fetch that data inside a React.useEffect callback and display the results when the request completes.

Instructor: [0:00] Here we have an app that's managing a Pokémon name state, and then we're rendering out a form, and we're rendering an input. Every time we submit our form, we're going to update the Pokémon name to whatever the user typed in the input.

[0:13] When this is re-rendered, we're going to render the Pokémon info with that Pokémon name, and then the Pokémon info should render our information based on that Pokémon. If we type in Pikachu, then we should request in formation for Pikachu.

[0:31] We need to get that information by fetching it from a server. We have this helper function here called fetch Pokémon that creates a Pokémon GraphQL query. Then we're using Window.fetch to fetch this public API that has Pokémon information.

[0:47] We're making a post. We We have our proper headers to accept JSON then we serialize and we specify our body is a JSON stringified version of our query. The variables for our query which is the name of the Pokémon.

[1:03] Then when that promise resolves we're going to take the response parse it as JSON and when that's done, we'll get that response object and pluck the Pokémon off of the data in the response. We can call this function to get the information for this Pokémon that we get as a prop but our render method here has to be synchronous.

[1:27] Our fetchPokémon function is asynchronous. Making HTTP request like this is a side effect so we're going to use the React useEffect hook. We'll say React.useEffect and the first thing that I want to say here is if there's no pokémonName, they haven't entered a Pokémon name yet or they submitted an empty one then we'll simply return. We don't need to make a request for that.

[1:52] Otherwise, we'll call that fetchPokémon with the pokémonName and then in our success handler for this promise, we'll get the Pokémon data and we can set some state. Let's go ahead and manage some state for this.

[2:07] We'll have use state for Pokémon and we'll call setPokémon, and we'll initialize this to null. Down here, let's rename this from Pokémon to pokémonData. Then we can call setPokémon with the pokémonData.

[2:25] Down here we can say if no Pokémon then we'll return just a ... to indicate the reloading. Otherwise we know we have the pokémonData and so, we can render it right here. Let's JSON stringify this. I'll put that in a pre so we get the right spacing. Say, JSON stringify Pokémon, null, two to get nice spacing for JSON.

[2:51] We'll save this. We have a ... right here. Because there's no Pokémon then we can enter in Pikachu, submit that, and we get Pikachu's information.

[3:01] In review, to do anything asynchronous, that is a side effect that needs to happen inside a useEffect callback. For our Pokémon info, we accept that pokémonName and in our callback, if there's no pokémonName specified, then we'll simply return. Otherwise, we'll fetch the pokémonData with that pokémonName.

[3:19] Then when we get that data back, we'll update our own state to have that data that will trigger re-rendering of Pokémon info. We can return the stringified version of that pokémonData. We could apply an optimization here to make sure that this useEffect only runs when we want it to by putting pokémonName in here.

[3:39] That way, this useEffect will only rerun when the pokémonName changes. We could also add an if statement here for if there's no pokémonName supplied, then we could say return, submit a Pokémon. With that we get submit a Pokémon then we can type in something like Pikachu. Submit that and we'll get Pikachu's information loaded up.

Brandon Perfetti
Brandon Perfetti
~ 10 months ago

Looks like the pokemon api referenced here is down.

I found something similar JIC anyone else hits the same trouble.

https://github.com/mazipan/graphql-pokeapi

Sample gql query:

query pokemon($name: String!) {
  pokemon(name: $name) {
    id
    name
    abilities {
      ability {
        name
      }
    }
    moves {
      move {
        name
      }
    }
    types {
      type {
        name
      }
    }
    message
    status
  }
}
Martin Moreno
Martin Moreno
~ 9 months ago

The API in this video no longer seems to be valid. Could you please update? I tried repurposing using https://pokeapi.co/api/v2/pokemon/ and it works but unfortunately only GET methods are allowed.

Iñigo Iparragirre
Iñigo Iparragirre
~ 2 months ago

If the url doesn't work update the fetch url to 'https://graphql-pokemon2.vercel.app'