A new startup, Reactive weather, has hired you to build a web application that renders real time weather data for cities around the world. This project will require that you utilize:
- Components
- Props
- State
- Conditional Rendering
- Controlled Inputs
fetch
and theuseEffect
Hook
GOAL: An array of weather data has been provided for you in data.js
. Render a WeatherCard
in App.js
for each city in the array and render the data for each city in the WeatherCard
.
- In the root directory, run the following to preview the app. This will refresh every time you save a file.
npm install npm start
- In
WeatherCard.js
, a card has been made for you, but hasn't been exported. Export the card usingmodule.exports
. - In
App.js
, import:- The
cities
array fromdata.js
. - The
WeatherCard
from/components/WeatherCard.js
.
- The
- Inside the
<div className = "app">
, use amap()
function to iterate through the cities array and return aWeatherCard
component for each item in the array. EachWeatherCard
component should receive the corresponding object with a key of data. - In
components/WeatherCard.js
, update thefunction WeatherCard
with aprops
parameter. - Update the
WeatherCard
so that it renders the:- City name
- Temperature
- Forecasted weather conditions
GOAL: Complete the following using your knowledge of state and conditional rendering:
- Adjust the icons to render based on the value stored in forecast (e.g. if it is rainy the rainy icon will render).
- Create a myLocation component to track the users current location and stores the value in state. This component will update with the weather for the users specific location. We will dynamically update this in future sections!
In components/WeatherCard.js
:
- There are three additional weather icons available in the
assets
folder. Import these at the top of the file just like thesunny
icon. - Conditionally render the icons based on the value stored in
props.data.forecast
. E.g. If it is "Rainy" than the rainy icon should render. There are multiple ways in which to achieve this output!
In App.js
:
We will be updating this state variable in Part 3. Today we are just working on setting up the functionality for hard coded state values.
- At the top of the file, import
useState
from the React library. - Create a new state variable called
location
and state setter function. Initialize it with a value for the city of your choice. - In the
components
folder, create aLocation.js
file. Import this intoApp.js
. - Pass the
data
,location
, and state setter function as props to theLocation
component.
In components/Location.js
:
- We need to search the
data
array passed as a prop to find the object that has the city that matches ourlocation
state. Explore how to use.find()
to achieve this. - Once you have found the corresponding data, return a card similar to the one in
WeatherCard.js
. It can look similar to the card below.- NOTE: It may help to turn the icon conditional rendering you wrote into a helper function and import it into this component so that you can use DRY principles.
GOAL: Create a Form
component that allows users to input their city and the program will output either:
- The weather for the city they input
- Some message informing the user that city is not in the array.
In App.js
:
- In the
components
folder, create aForm.js
file. Import this intoApp.js
. - Render the
Form
component near the top of your application. Pass it thelocation
state andsetLocation
state setter function as props.
In components/Form.js
:
-
Destructure the
location
andsetLocation
props. -
Return a
<form>
element that has an<input>
element that will accept a city input and<button>
element. Feel free to create your own or you can use the template code below:<div className = "form"> <form> <label className = "city">City: <input type="text"/> </label> <button className = "btn btn-primary" type="submit" >Submit</button> </form> </div>
-
Assign the
<input>
a value oflocation
and create anonChange
event handler that sets thelocation
to the current value of the<input>
usinge.target.value
.
Try out your form. Oh no! There's an error. Why? Currently the location state is updating every time you type and this is causing the application to error out.
- Import
useState
from the React library. - Create a new piece of state called
typedLocation
and a state setter function. Initialize it as an empty string. - Update the
<input>
value astypedLocation
. Update theonChange
event handler to settypedLocation
to the current value of<input>
usinge.target.value
. - Create a
handleSubmit
function that does the following:- Accept the event as a parameter
- Prevent the default form behavior using
e.preventDefault()
. - Call
setLocation
and pass it the current value oftypedLocation
. - Reset
typedLocation
to an empty string using the state setter function.
- In the
<form>
opening tag, create anonSubmit
event handler and pass it thehandleSubmit
function. - Try out the form! It should work for any city in the array and should throw an error if you type a city that doesn't match.
In components/Location.js:
The user may submit a location that isn't in the array, we want to make sure that the program can handle this.
- If the location is not found in the
data
array, render a message to the user like"Location not found"
or something similar. - Try submitting an incorrect location to verify that your application can handle this input.
We want users to be able to search ANY location, not just some hard coded data. Luckily, there are many weather APIs we can hook up to our application! Explore the following APIs and decide which one works best for you:
- Open Metro - No API Key required, buy you will need to figure out how to convert locations into coordinates.
- AccuWeather - API Key required. Make sure to use a
.env
and thedotenv
package to read environment variables. - Any other free weather API you can find. Here's a full list of free weather APIs
This is fairly open ended based on the API you select, but a few things to consider trying.
- Select a Weather API from the options above. Explore the documentation for how to access the endpoint and the structure of the data that is returned.
- Update the
Location
component with a call that initiates afetch
call to your endpoint(s) every time thelocation
state is updated.- NOTE: You can add a variable to your dependency array for
useEffect
so that it runs only when that variable is updated.
useEffect(() => { // DO SOMETHING }, [updatedVariable]) // useEffect only runs when updatedVariable changes.
- NOTE: You can add a variable to your dependency array for
- Most of the APIs will require you to either provide coordinate points and/or city IDs in order to Based on the user input, render a 1 day, 5 day, or 10 day forecast.
- Allow the user to specify if they want different information like Celsius vs. Fahrenheit or the amount of precipitation. Customize the outputs to respond to these inputs.