Create a weather Application using React Redux

Weather App is a web application designed to provide real-time weather information for any location worldwide. In this article, we will make a Weather App using React and Redux. It offers a seamless and intuitive user experience, allowing users to easily access accurate weather forecasts ( temperature, wind speed, humidity etc.) by just entering any city name.

Project preview:

Weather App

Prerequisites:

Approach

  • React App & dependencies : Use Create React App to set up a new React project named weather-app and install Redux, React Redux and Axios.
  • Redux Setup : Create a store.js file to set up the Redux store, define required reducers and actions and use createStore method to create store.
  • Weather API : Select a weather API platform, create an account, and integrate its keys and endpoint into your React app.
  • Component : Implement weather display, location input, loading indicator, and error message in the weather app and also integrating Redux state and actions.

Steps to Create React Application

Step 1: Create React Application named weather-app and navigate to it using this command.

npx create-react-app weather-app
cd weather-app

Step 2: Install required packages and dependencies.

npm install react-redux redux axios

Updated dependencies in package.json file

Installed dependencies will look like the below file in package.json file.

 "dependencies": {
"axios": "^1.6.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^9.1.1",
"redux": "^5.0.1"
},

File structure:

Project Structure

Example:

CSS
/* App.css */

#App-wrapper {
  /* text-align: center; */
  justify-content: center;
  display: flex;
}
#app {
  text-align: center;
  width: 500px;
  display: flex;
  flex-direction: column;
}

#head {
  display: flex;
  gap: 10px;
  align-items: center;
}

input {
  padding: 10px 20px;
  border: 1px solid black;
  margin: 5px;
}
button {
  padding: 10px 20px;
  border: 1px solid black;
  /* margin: 5px; */
  cursor: pointer;
  background-color: rgb(230, 230, 230);
}
button:hover {
  background-color: rgba(9, 204, 9, 0.61);
}

p {
  background-color: rgb(230, 230, 230);
  padding: 10px 20px;
  margin: 5px 0px;
  text-transform: capitalize;
}
p span {
  color: green;
}
JavaScript
// store.js 

import { createStore, combineReducers } from "redux";
// actions

export const fetchWeatherRequest = () => ({
  type: "FETCH_WEATHER_REQUEST",
});

export const fetchWeatherSuccess = (data) => ({
  type: "FETCH_WEATHER_SUCCESS",
  payload: data,
});

export const fetchWeatherFailure = (error) => ({
  type: "FETCH_WEATHER_FAILURE",
  payload: error,
});

// reducers/weatherReducer.js
const initialState = {
  weatherData: null,
  loading: false,
  error: null,
};

const weatherReducer = (state = initialState, action) => {
  switch (action.type) {
    case "FETCH_WEATHER_REQUEST":
      return {
        ...state,
        loading: true,
        error: null,
      };
    case "FETCH_WEATHER_SUCCESS":
      return {
        ...state,
        loading: false,
        weatherData: action.payload,
      };
    case "FETCH_WEATHER_FAILURE":
      return {
        ...state,
        loading: false,
        error: action.payload,
      };
    default:
      return state;
  }
};

// store.js

const rootReducer = combineReducers({
  weather: weatherReducer,
  // Add more reducers if needed
});

const store = createStore(rootReducer);

export default store;
JavaScript
// App.js

import React, { useState } from "react";
import axios from "axios";
import { connect } from "react-redux";
import {
  fetchWeatherRequest,
  fetchWeatherSuccess,
  fetchWeatherFailure,
} from "./store";
import "./App.css";

const WeatherApp = ({ weatherData, loading, error, fetchWeather }) => {
  const [city, setCity] = useState("");

  const findHandle = async () => {
    await fetchWeather(city);
  };

  console.log(weatherData);
  return (
    <div id="App-wrapper">
      <div id="app">
        <div id="head">
          <img
            src="https://media.w3wiki.net/gfg-gg-logo.svg"
            alt="gfg_logo"
          />
          <label>Enter City Name</label>
          <input
            type="text"
            value={city}
            onChange={(e) => setCity(e.target.value)}
          />
          <button onClick={findHandle}>Find</button>
        </div>
        <div>
          {loading && <p>Loading...</p>}
          {error && <p>Error: {error}</p>}
          {weatherData && (
            <div>
              <div>
                <img src={weatherData?.current?.condition.icon} />
                <p>{weatherData?.current?.condition.text}</p>
              </div>
              <div>
                <p>
                  Temperature : <span>{weatherData?.current?.temp_c}c</span>
                </p>
                <p>
                  Humidity : <span>{weatherData?.current?.humidity}</span>
                </p>
                <p>
                  Wind Speed : <span>{weatherData?.current.wind_kph}kph</span>
                </p>
              </div>
              <div>
                {Object.keys(weatherData?.location).map((key) => (
                  <p key={key}>
                    {key} : <span>{weatherData.location[key]}</span>
                  </p>
                ))}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

const mapStateToProps = (state) => ({
  weatherData: state.weather.weatherData,
  loading: state.weather.loading,
  error: state.weather.error,
});

const mapDispatchToProps = (dispatch) => ({
  fetchWeather: (city) => {
    dispatch(fetchWeatherRequest());
    fetchWeatherData(city)
      .then((data) => dispatch(fetchWeatherSuccess(data)))
      .catch((err) => dispatch(fetchWeatherFailure(err.message)));
  },
});

// feathermatch function

async function fetchWeatherData(city = "Delhi") {
  const API_KEY = "XXXXX-XXXXX-XXXXX";
  const response = await axios.get(
    `https://api.weatherapi.com/v1/current.json?q=${city}&key=${API_KEY}`
  );
  console.log(response);
  if (response.status != 200) {
    throw new Error("Failed to fetch weather data");
  }
  return response.data;
}

export default connect(mapStateToProps, mapDispatchToProps)(WeatherApp);
JavaScript
// index.js 

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux";
import  store  from "./store";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);


Command to Run Weather Application:

To run weather application open your terminal and navigate to weather-app directory and enter the following command.

npm start

Output:

Weather App




Contact Us