Building a Dynamic Weather App with React JS: A Step-by-Step Guide

Photo by NOAA on Unsplash

Building a Dynamic Weather App with React JS: A Step-by-Step Guide

ยท

4 min read

Hello Fellow Developers,

Today Let's Build a Dynamic Weather App In React JS.

Step 1.

Create your React app, I am using Vite to create a React App

npm create vite@latest
chose React framework and choose Javascript
after that
cd in to that react app folder name "Weather APP"
npm i

for running that initial code 
npm run dev

Now Create a Component folder in the src folder, In the Component folder - create one more folder named "Assets" In this you will place the icon that we use in this app. (you can find it on GitHub link, i will give in last of this blog), create two more file "WeatherApp.css" and "WeatherApp.jsx"

Step 2. This is the code for creating the weather app.

const apiKey = "YOUR WEATHER API KEY";

import "./WeatherApp.css";
import searchIcon from "./Assets/search.png";
import clearIcon from "./Assets/clear.png";
import cloudIcon from "./Assets/cloud.png";
import drizzleIcon from "./Assets/drizzle.png";
import humidityIcon from "./Assets/humidity.png";
import rainIcon from "./Assets/rain.png";
import snowIcon from "./Assets/snow.png";
import windIcon from "./Assets/wind.png";
import { useState } from "react";

function WeatherApp() {
  const [city, setCity] = useState("");
  const [weatherData, setWeatherData] = useState("");
  const [error, setError] = useState(null);
  const [weatherIcon, setWeatherIcon] = useState("")
  const apiURL = `https://api.openweathermap.org/data/2.5/weather?units=metric&q=${city}&appid=${apiKey}`;

  const search = async () => {
    try {
      const response = await fetch(apiURL); //fetching the URL

      if (response.ok) { //checking the response
        const data = await response.json(); //change that response to json
        setWeatherData(data);
        setError(null);
        setCity("");

        // Set weather icon based on weather condition
        if (data.weather[0].main === 'Clouds') {
          setWeatherIcon(cloudIcon);
        } else if (data.weather[0].main === 'Clear') {
          setWeatherIcon(clearIcon);
        } else if (data.weather[0].main === 'Drizzle') {
          setWeatherIcon(drizzleIcon);
        } else if (data.weather[0].main === 'Rain') {
          setWeatherIcon(rainIcon);
        } else if (data.weather[0].main === 'Snow') {
          setWeatherIcon(snowIcon);
        }
      } else if (response.status === 404) {
        setError("City Not Found");
        setWeatherData(null);
      } else {
        setError("Error fetching weather data");
        setWeatherData(null);
      }
    } catch (error) {
      setError("Error fetching weather data");
      setWeatherData(null);
    }
  };

  return (
    <>
      <div className="container">
        <div className="top-bar">
          <input
            className="cityInput"
            type="text"
            placeholder="Enter City"
            value={city}
            onChange={(e) => setCity(e.target.value)}
          ></input>
          <div className="search-icon">
            <img
              src={searchIcon}
              className="searchIcon"
              onClick={() => search()}
            />
          </div>
        </div>

        {weatherData && (
          <>
            <div className="weather-image">
              <img src={weatherIcon} className="weatherIcon" />
            </div>
            <div className="weather-temp">{Math.floor(weatherData.main.temp)}&deg;C</div>
            <div className="weather-location">{weatherData.name}</div>

            <div className="data-container">
              <div className="element">
                <img className="icon" src={windIcon}></img>
                <div className="data">
                  <div className="text">{Math.floor(weatherData.wind.speed)}km/h</div>
                  <div className="wind-present">Wind</div>
                </div>
              </div>

              <div className="element">
                <img className="icon" src={humidityIcon}></img>
                <div className="data">
                  <div className="text">{weatherData.main.humidity}%</div>
                  <div className="humidity-present">Humidity</div>
                </div>
              </div>
            </div>
          </>
        )}

        {error && <div className='error-message'>{error}</div>}
      </div>
    </>
  );
}
export default WeatherApp;

Step 3: Here is the code for CSS for this Weather APP

.container{
  width: 700px;
  height: 790px;
  margin: auto;
  margin-top: 50px;
  border-radius: 14px;
  background: linear-gradient(180deg, rgb(202, 124, 225), #6313a5);
}
.top-bar{
  display:flex;
  justify-content: center;
  gap: 15px;
  padding-top: 40px;
}
.top-bar input{
  display: flex;
  width: 500px;
  height: 75px;
  background: #ebfffe;
  border: none;
  outline: none;
  border-radius: 40px;
  padding-left: 45px;
  color: #626262;
  font-size: 22px;
  font-weight: 700;
}
.search-icon{
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 40px;
  width: 78px;
  height: 78px;
  background-color: #ebfffe;
  cursor: pointer;
}
.search-icon .searchIcon{
  width: 20px;
  height: 25px;
}

.weather-image{
  margin-top: 20px;
  display: flex;
  justify-content: center;
}
.weather-temp{
  display: flex;
  justify-content: center;
  color: #fff;
  font-size: 90px;
  font-weight: 400;
}
.weather-location{
  display: flex;
  justify-content: center;
  color: wheat;
  font-size: 50px;
  font-weight: 400;
}
.data-container{
  margin-top: 50px;
  color: white;
  display: flex;
  justify-content: center;
}
.element {
  margin: auto;
  gap: 19px;
  display: flex;
  align-items: flex-start;
}
.icon{
  margin-top: 10px;
}
.data{
  font-size: 35px;
  font-weight: 400;
}
.wind-present, .humidity-present{
  font-size: 20px;
  font-weight: 400;
}
.error-message{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: linear-gradient(262deg,rgba(0,0,0,0.1),rgba(0,0,0,0.4)) ;
  color: red;
  margin-top: 60px;
  font-size: 34px;
  font-weight: 400;
}

Step 4. Changement in App.jsx

import WeatherApp from "./Components/WeatherApp"

function App() {

  return (
    <>
      < WeatherApp />
    </>
  )
}

export default App

Feel free to style your Weather App using CSS or your favorite styling library. Add some extra features like displaying icons based on weather conditions or a 5-day forecast.

GitHub

Follow on Twitter

And there you have it โ€“ your very own Weather App using React JS! ๐ŸŒฆ๏ธ This project not only helped me celebrate my coding journey but also allowed me to explore React and API integration. I hope you enjoyed this tutorial as much as I did building it. Happy coding, and here's to more years of learning and coding adventures! ๐Ÿš€๐ŸŽ‰

ย