Hey! I'm on a mission to make 100 React.js projects ending March 31st. Please follow my dev.to profile or my twitter for updates and feel free to reach out if you have questions. Thanks for your support!
Link to the deployed project: Link
Link to the repo: github
This was a quick video, and I actually had a blast doing it. I'm sometimes not the biggest fan of Brad Traversy's long form videos because I don't feel I absorb much with code-along tutorials, but shorter videos covering material you mostly know and want practice with are excellent and his video creating a React Wildfire Tracker fit the bill for a late Saturday night coding session.
The data for this website comes from NASA. This was my first time using their API so that was a pleasure. We made use of their Events API which tracks natural events going on in the world. This was also my first app using Google Maps. In previous projects I had opted for Mapbox because it was free, but I do enjoy Google Maps' bright color scheme that feels like a real map (vs an app) and easy navigation. To display the map in React I used the google-map-react
npm package.
Other npm packages I made use of included LoaderSpinner
for an animated spinner on loading screens, the Iconify icon package at @iconify/react
and specifically their Material Design icon library at @iconify/icons-mdi
. I also used dotenv
to save sensitive API info in process variables. I accidentally forgot to put the Header in my components folder. Forgive me for it.
First, in our App
component we import useState
and useEffect
from the React package. We then create two pieces of state- loading
and eventData
. Loading will be a boolean that indicates whether the data is being fetched. We will use it to display a loading spinner if it is true. eventData
will be an empty array until our fetch method returns data. We'll use useEffect
to fetch data from the API on page load.
import React,{useState,useEffect} from 'react'
import LoaderSpinner from './components/LoaderSpinner'
import Map from './components/Map'
import Header from './Header'
function App() {
const [eventData,setEventData] = useState([])
const [loading,setLoading] = useState(false)
useEffect(() => {
const fetchEvents = async () => {
setLoading(true)
const res = await fetch('https://eonet.sci.gsfc.nasa.gov/api/v2.1/events')
const {events} = await res.json()
setEventData(events)
setLoading(false)
}
fetchEvents()
console.log(eventData)
}, [])
return (
<div>
<Header />
{!loading ? <Map eventData={eventData} /> : <LoaderSpinner />}
</div>
);
}
export default App;
LoaderSpinner
is a separate component that uses the react-loader-spinner
package. According to the documentation you'll need to manually load in the CSS. I chose the ThreeDots type variant because I thought it looked the most professional.
import React from 'react'
import Loader from 'react-loader-spinner'
import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css'
const LoaderSpinner = () => {
return (
<div className='loader-spinner'>
<Loader
type="ThreeDots"
color="#000000"
height={100}
width={100}
/>
<h1>Fetching Fire Data...</h1>
</div>
)
}
export default LoaderSpinner
In the Map component, we use GoogleMapReact
to render a Google Map. You'll need to give the map component a center point in coordinates, a zoom level and your API key. Mine is stored in a .env
file. I also gave the center
prop a set of defaultProps
with the coordinates.
The Google Map component is pretty neat because you can give it children and if the children have lat
and lng
props the map will put them in the right place on the map.
We also provide an onClick
handler to the LocationMarker
component so that when a fire icon is clicked we set the locationInfo
state to an object with data relevant to the fire.
import React,{useState} from 'react'
import GoogleMapReact from 'google-map-react'
import LocationMarker from './LocationMarker'
import LocationInfoBox from './LocationInfoBox'
const Map = ({eventData,center,zoom}) => {
const [locationInfo,setLocationInfo] = useState(null)
const markers = eventData.map(ev => {
if (ev.categories[0].id === 8) {
return (
<LocationMarker
key={ev.id}
lat={ev.geometries[0].coordinates[1]}
lng={ev.geometries[0].coordinates[0]}
onClick={() => {setLocationInfo({
id: ev.id,
title: ev.title,
lat: ev.geometries[0].coordinates[1],
long: ev.geometries[0].coordinates[0]
})}}
/>)
}
return null
})
return (
<div className='map'>
<GoogleMapReact
bootstrapURLKeys={{key: process.env.REACT_APP_GOOGLE_API_KEY}}
defaultCenter={center}
defaultZoom={zoom}
>
{markers}
</GoogleMapReact>
{locationInfo && <LocationInfoBox info={locationInfo} />}
</div>
)
}
Map.defaultProps = {
center: {
lat: 42.3265,
lng: -122.8756
},
zoom: 6
}
export default Map
This is the kind of project I love because it has immediate real world application. Hope you like it!
Top comments (1)
Suggest a path or learning resources for developing a very complex form using react hook or any other library.