Let's build a Corona virus Tracker app with React. We will be using this free API Corona Stats that @mathdroid has kindly made for us.
This will be a basic code along style article.
File cleanup
In create react app clean up the files you don't need. Then create a a DisplayContainer
component and import it into App
. Or do your prefered way of filing.
import React from "react"
function App() {
return <div>Hello World</div>
}
export default App
Display Container
import React from "react"
const DisplayContainer = () => {
return <div>DISPLAY CONTAINER</div>
}
export default DisplayContainer
import DisplayContainer from "./components/DisplayContainer"
function App() {
return (
<div>
<DisplayContainer />
</div>
)
}
Fetching the data
We are going to use Reacts useState
and useEffect
hooks.
-
useState
allows you to add state to a functional component in React -
useEffect
is used for when you want something to happen when the page is rendered or a change is made.
Start by importing useState
and useEffect
from React. Then create the state to use. We want loading, error and stats state as these are the things we want to manage.
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const [stats, setStats] = useState([])
Our function will be an async/await
function. I'm going to use a try/catch/finally
block for this. I find it's nice and easy to visualise like this.
import React, { useState, useEffect } from 'react';
const DisplayContainer = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [stats, setStats] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
} catch (error) {
} finally {
}
}
})
We have our state and layout laid out let's add the rest.
Fetching data and set state
try - we need to get the data from our end point using fetch
. Then convert the data to JSON
for us to use. Next set the state with this JSON
data.
try {
const response = await fetch("https://covid19.mathdro.id/api")
const data = await response.json()
setStats(data)
}
catch - In our catch block we set the error state. If there is an error that is.
} catch (error) {
setError(error);
}
finally - The last thing we want this function to do is set the loading state to false.
finally {
setLoading(false);
}
The full data fetching function looks like this.
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("https://covid19.mathdro.id/api")
const data = await response.json()
setStats(data)
} catch (error) {
setError(error)
} finally {
setLoading(false)
}
}
setLoading(true)
fetchData()
}, [])
Notice at the end of useEffect
there is an empty array []
. This is where dependencies go to perform this function again. You must add an empty array for this else you will encounter the dreaded infinite loop.
Now check the state in your React dev tools to see if it has worked successfully. We want the confirmed, recovered and deaths stats from the api.
Displaying the data
If you checked the state in the dev tools you'll see our state is an object with objects.
Now if you try to display the stats like this stats.confirmed.value
you will get an error TypeError: stats.confirmed is undefined
. This is because you are trying to display something that doesn't exist yet. You must first check if it exists. This is done with a simple ternary operator
.
- ternary operator - "If this is true, do this, if not do this instead."
return (
<div style={{ textAlign: `center` }}>
<h2>Confirmed:</h2>
<span>
{stats.confirmed ? stats.confirmed.value : "Sorry not available"}
</span>
<h2>Deaths:</h2>
<span>{stats.deaths ? stats.deaths.value : "Sorry not available"}</span>
<h2>Recovered:</h2>
<span>
{stats.recovered ? stats.recovered.value : "Sorry not available"}
</span>
</div>
)
Finish
There we have the Corona virus stats displayed.
import React, { useState, useEffect } from "react"
const DisplayContainer = () => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const [stats, setStats] = useState({})
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("https://covid19.mathdro.id/api")
const data = await response.json()
setStats(data)
} catch (error) {
setError(error)
} finally {
setLoading(false)
}
}
setLoading(true)
fetchData()
}, [])
return (
<div style={{ textAlign: `center` }}>
<h2>Confirmed:</h2>
<span>
{stats.confirmed ? stats.confirmed.value.toLocaleString() : null}
</span>
<h2>Deaths:</h2>
<span>{stats.deaths ? stats.deaths.value.toLocaleString() : null}</span>
<h2>Recovered:</h2>
<span>
{stats.recovered ? stats.recovered.value.toLocaleString() : null}
</span>
</div>
)
}
export default DisplayContainer
I have used .toLocaleString()
to format the numbers. Now it just needs some CSS.
Top comments (0)