Getting data with Axios is easy, but rendering it ~OMFG~
You may know how to fetch data with Axios, but how do you render it to React?
Maybe you tried something like using
await in render function to make React wait for your request before rendering. But when you do something like:
You'll get an error like this:
async operator makes the
render function to return a
Promise, which is an object and React doesn't know to render objects.
So, how do you make React wait for your function before render?
Well, the answer is: faking it 😏
Waiting for Axios before rendering
There is a fetching recipe for doing this which is always the same:
- Start your component in "loading mode"
- When your component "mounts" do the request.
- When the request is done, save your data and turn off "loading mode".
- Make sure that while your component is in "loading mode", display a spinner or loading text in your render function. And when not, display your data.
How do you do this in code?
Look at this simple React app that fetches data about a single Pokémon and displays its name and picture:
Here is the implementation:
How is this translated to our recipe?
1) Start your component in "loading mode"
With the conditional rendering of "Loading..." text and by using useState we accomplish the "loading mode" state of the component.
Why are we using useState instead of a simple const? Because we want to make App component remember this value between renders!
The first render displays "Loading..." in the browser.
2) When your component "mounts" do the request
useEffect receives a function that will be called after the DOM (what the browser shows) is updated. Here we tell axios to fetch Charmander data from PokeApi.
axios.get is executed asynchronous, so nothing is changed.
3) When the request is done, save your data and turn off "loading mode"
When request is done, we update the state of our component by using
Both calls update the state:
So... there are 2 renders! 🤯
The second render (triggered by
setPokemon) will do nothing in the browser because
true → component returns "Loading..." again.
The third render (triggered by
setLoading) will show Charmander in the browser! Because this time
false, so we reach the end of the function were the pokemon is finally rendered.
Summing-up this confusing render stuff:
Not familiar with hooks?
Hey! Is 2020, you should! 😂
No problem. Here is the equivalent code with class component: