How to Create Weather App in React

In this article, we are going to build a weather app in React. In this project, we will be using OpenWeather API which provides us free API to get weather details. Here we will add an input field where user will add any city name and as soon as the city name is entered there will be an API call and the details will be brought to the screen. This app will be completely API dependent.

So basically this is going to be a beginner-friendly project, so let’s build this project step by step.

Prerequisites for creating a calculator in React

  • Basic knowledge of ReactJS.
  • Basic knowledge of React Hooks.
  • Good knowledge of React components.

Adding API and Keys

Now before jumping into the code, let’s get to the API and Key that we will be using for this project. For that, we need to visit the openweather.org site and just login to get the API key. After that, in our App.js component, we’ve added a constant to which we’ve assigned our API key to the key constant, and we’ve provided a URL to our base constant. Also we have two nice pictures which will be different in certain situation.

import React, { useState } from 'react';
const api = {
key: "4f8e795dcd6dbf7b9f5276bff095ffc1",
base: "https://api.openweathermap.org/data/2.5/"
}

making skeleton for app

Now let’s move on to our return statement to create the skeleton for the weather app. Here we have added a class and an input field with a placeholder. Then we’ve added another

Added for location with the starting location for the -box and then for checking the output. Finally we have added one more div where we will add date where we will get date using datebuilder function.

` return (

< input
type = “text”
classname = “search-bar”
placeholder = “Search…”

      />
    </div>
    <div>
      <div className="location-box">
        <div className="location">New York City, US</div>
        <div className="date">{dateBuilder(new Date())}</div>
      </div>
      </div>
  </main>
</div>

,

date of creation

Now let’s take today’s date, for that we have added a function named dateBuilder(), here we have added an array for the months with the names of all the months. Then we’ve added another array for the days with the names of all the days. Also “d” here is the Date() object we passed from the function call. After that we have added a variable for days, here we have used days[d.getDay()]getDay() is a function to get the current day.

Then we have fetched the month and year for the date and so on, which are returned on the function call. Here you can see that we have created separate arrays of months and days because the getDay() and getMonth() functions return the day and month number respectively, so we only need the month name and not the day number.

`const DateBuilder = (d) => {
let the month = [“January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”],
let’s day [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”],

let day = days[d.getDay()];
let date = d.getDate();
let month = months[d.getMonth()];
let year = d.getFullYear();

return `${day} ${date} ${month} ${year}`

,

connecting states

After that, we have to add our states, one for the question and the other for the season. Here the query is to generate the URL for the Weather API and is for the weather details. Then we have added the onchange event to the input where we are calling the query, and we are also calling the function called search on the onkeypress event.

function App() {
const [query, setQuery] = useState('');
const [weather, setWeather] = useState({});
return (
<div className=>
<main>
<div className="search-box">
<input
type="text"
className="search-bar"
placeholder="Search..."
onChange={e => setQuery(e.target.value)}
value={query}
onKeyPress={search}
/>
</div>
);}

Calling API to get result

Now that we have defined the search function, we have added a condition where if evt.key is equal to enter. If yes, we have used fetch() where we have this line of code to make ${api.base}weather?q=${query}&appid=${api.key}&units=metric API call And this is the query syntax for URL, and we used then(res => res.json()) to get the result in JSON format. After that we have updated the weather and query states.

const search = evt => {
if (evt.key === "Enter") {
fetch(
${api.base}weather?q=${query}&appid=${api.key}&units=metric)
.then(res => res.json())
.then(result => {
setWeather(result);
setQuery('');
console.log(result);
});
}
}

update the skeleton

Now that we are almost done, here we have to update our skeleton to get the final version of the app. Here

With a condition to check the weather. main is not equal undefined, if yes then we will add app warm class otherwise app class. These classes have some CSS to change the background picture and style.

Then we have checked again that the weather check is not undefined, then we will display the location box and the weather box. On Location, we have assigned location and country dynamically. Then in the weather box, we have named the temperature and the weather.

return (
<div className={(typeof weather.main != "undefined") ? ((weather.main.temp > 16) ? 'app warm' : 'app') : 'app'}>
<main>
<div className="search-box">
<input
type="text"
className="search-bar"
placeholder="Search..."
onChange={e => setQuery(e.target.value)}
value={query}
onKeyPress={search}
/>
</div>
{(typeof weather.main != "undefined") ? (
<div>
<div className="location-box">
<div className="location">{weather.name}, {weather.sys.country}</div>
<div className="date">{dateBuilder(new Date())}</div>
</div>
<div className="weather-box">
<div className="temp">
{Math.round(weather.main.temp)}°c
</div>
<div className="weather">{weather.weather[0].main}</div>
</div>
</div>
) : ('')}
</main>
</div>
);

customizing the application

Now our structure is great, and we’ve added up almost everything, but before moving on to the next step, let’s add some color and customize this calculator, so that it looks at least like a calculator. I won’t go deep into CSS because CSS is really up to you and it’s not that hard to have a color or something. So if you want the same CSS then use the below CSS.

index.css

,
margin: 0;
padding: 0;
box-sizing: border-box;
,

Body {
font-family: ‘Montserrat’, sans serif;
,

.application {
background-image: url(‘./assets/cold-bg.jpg’);
background-size: cover;
background-position: bottom;
Transition: 0.4 Ease;
,

.app.hot {
background-image: url(‘./assets/warm-bg.jpg’);
,

Main {
Minimum altitude: 100vh;
background-image: linear-gradient(from bottom, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.75));
padding: 25px;
,

.search box {
width: 100%;
margin: 0 0 75px;
,

.search-box .search-bar {
display area;
width: 100%;
Padding: 15px;

Appearance: none;
background: none;
limit: none;
outline: none;

background-color: rgba(255, 255, 255, 0.5);
border-radius: 0px 0px 16px 16px;
margin-top: -25px;

box-shadow: 0px 5px rgba(0, 0, 0, 0.2);

Color: #313131;
font-size: 20px;

Transition: 0.4s Ease;
,

.search-box .search-bar:focus {
background-color: rgba(255, 255, 255, 0.75);
,

location-box. place {
Color: #FFF;
font-size: 32px;
font-weight: 500;
text-align: center;
text-shadow: 3px 3px rgba(50, 50, 70, 0.5);
,

.location-box .date {
Color: #FFF;
font-size: 20px;
font-weight: 300;
font-style: italic;
text-align: center;
text-shadow: 2px 2px rgba(50, 50, 70, 0.5);
,

weather-box {
text-align: center;
,

.weather-box .temp {
position: relative;
display: inline-block;
margin:30px auto;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 16px;

padding: 15px 25px;

Color: #FFF;
font-size: 102px;
font-weight: 900;

text-shadow: 3px 6px rgba(50, 50, 70, 0.5);
text-align: center;
box-shadow: 3px 6px rgba(0, 0, 0, 0.2);
,

.weather-box .weather {
Color: #FFF;
font-size: 48px;
font-weight: 700;
text-shadow: 3px 3px rgba(50, 50, 70, 0.5);
,
,
read more

Leave a Comment