Code a Weather App in React, part 1

Here's one way to code a Weather App in React, using Axios

By: Ajdin Imsirovic 23 March 2023

Here is a step-by-step guide to creating a weather app using React with hooks and Axios.

Step 1: Create a new React App

First, let’s create a new React app using the create-react-app command. Open up your terminal and run the following command:

npx create-react-app weather-app

This will create a new directory named weather-app with all the necessary files to get started.

Step 2: Install dependencies

Next, let’s install some dependencies we’ll need for our weather app. Run the following command in your terminal:

cd weather-app
npm install axios moment react-icons --save

Here we’re installing two packages:

  • moment - A lightweight date library that we’ll use to format the dates.
  • react-icons - A library of icons that we can use in our app.

Step 3: Create a new component

Now, let’s create a new component for our weather app. In the src directory, create a new file named Weather.js. This will be our main component for displaying the weather.

import React from 'react';

const Weather = () => {
  return (
    <div>
      <h1>Weather App</h1>
    </div>
  );
};

export default Weather;

Here, we’re importing React and creating a simple functional component that returns a div with an h1 tag. We’ll add more to this component in the following steps.

Step 4: Create a state using useState hook

Let’s create a state to hold the current weather data. We’ll use the useState hook for this. Update the Weather.js file as follows:

import React, { useState } from 'react';

const Weather = () => {
  const [weather, setWeather] = useState(null);

  return (
    <div>
      <h1>Weather App</h1>
    </div>
  );
};

export default Weather;

Here, we’re importing the useState hook from React and creating a state called weather. The useState hook takes an initial value, which we’ve set to null.

Step 5: Create a function to fetch weather data using fetch

Next, let’s create a function that will fetch weather data from an API using the fetch API. Add the following code to the Weather.js file:

import React, { useState, useEffect } from 'react';

const Weather = () => {
  const [weather, setWeather] = useState(null);

  const fetchWeather = async () => {
    try {
      const response = await fetch(
        'https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY'
      );
      const data = await response.json();
      setWeather(data);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    fetchWeather();
  }, []);

  return (
    <div>
      <h1>Weather App</h1>
    </div>
  );
};

export default Weather;

Here, we’re creating a new function called fetchWeather that uses the fetch API to fetch weather data from the OpenWeatherMap API. Note that we’ve hardcoded the city name and API key in this example. You should replace YOUR_API_KEY with your own OpenWeatherMap API key.

In addition, we’re using the useEffect hook to call the fetchWeather function when the component mounts. This ensures that the weather data is fetched and stored in the weather state as soon as the component is rendered.

Step 6: Display weather data in the component

Now that we have weather data in our state, let’s display it in the component. Update the return statement in the Weather component as follows:

import React, { useState, useEffect } from 'react';

const Weather = () => {
  const [weather, setWeather] = useState(null);

  const fetchWeather = async () => {
    try {
      const response = await fetch(
        'https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY'
      );
      const data = await response.json();
      setWeather(data);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    fetchWeather();
  }, []);

  if (!weather) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>Weather App</h1>
      <h2>{weather.name}</h2>
      <p>{weather.weather[0].description}</p>
      <p>Temperature: {weather.main.temp}</p>
      <p>Feels Like: {weather.main.feels_like}</p>
      <p>Humidity: {weather.main.humidity}</p>
    </div>
  );
};

export default Weather;

Here, we’re checking if weather is null. If it is, we’re displaying a loading message. Otherwise, we’re displaying the weather data in the component. We’re displaying the city name, weather description, temperature, feels like temperature, and humidity.

Step 7: Add styling to the component

Finally, let’s add some styling to the component using CSS. Create a new file named Weather.css in the src directory, and add the following code:

.weather {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: Arial, Helvetica, sans-serif;
}

.weather h1 {
  font-size: 3rem;
  margin: 2rem 0;
}

.weather h2 {
  font-size: 2rem;
  margin: 1rem 0;
}

.weather p {
  font-size: 1.5rem;
  margin: 0.5rem 0;
}

Next, import this CSS file in the Weather.js component and add the weather class to the main div. Update the Weather.js file as follows:

import React, { useState, useEffect } from 'react';
import './Weather.css';

const Weather = () => {
  const [weather, setWeather] = useState(null);

  const fetchWeather = async () => {
    try {
      const response = await fetch(
        'https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY'
      );
      const data = await response.json();
      setWeather(data);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    fetchWeather();
  }, []);

  if (!weather) {
    return <div>Loading...</div>;
  }

  return (
    <div className="weather">
      <h1>Weather App</h1>
      <h2>{weather.name}</h2>
      <p>{weather.weather[0].description}</p>
      <p>Temperature: {weather.main.temp}</p>
      <p>Feels Like: {weather.main.feels_like}</p>
      <p>Humidity: {weather.main.humidity}</p>
    </div>
  );
};

export default Weather

Step 8: Update the city dynamically

Now that our weather app is complete, let’s add the ability for the user to enter a city name and see the weather for that city. We’ll do this by adding an input field and a button to the component. When the user enters a city name and clicks the button, we’ll update the state with the weather data for the new city.

Update the Weather component as follows:

import React, { useState, useEffect } from 'react';
import './Weather.css';

const Weather = () => {
  const [city, setCity] = useState('London');
  const [weather, setWeather] = useState(null);

  const fetchWeather = async () => {
    try {
      const response = await fetch(
        `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`
      );
      const data = await response.json();
      setWeather(data);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    fetchWeather();
  }, [city]);

  const handleCityChange = (event) => {
    setCity(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    fetchWeather();
  };

  if (!weather) {
    return <div>Loading...</div>;
  }

  return (
    <div className="weather">
      <h1>Weather App</h1>
      <form onSubmit={handleSubmit}>
        <label htmlFor="city">City:</label>
        <input
          type="text"
          id="city"
          name="city"
          value={city}
          onChange={handleCityChange}
        />
        <button type="submit">Submit</button>
      </form>
      <h2>{weather.name}</h2>
      <p>{weather.weather[0].description}</p>
      <p>Temperature: {weather.main.temp}</p>
      <p>Feels Like: {weather.main.feels_like}</p>
      <p>Humidity: {weather.main.humidity}</p>
    </div>
  );
};

export default Weather;

Here, we’ve added an input field and a button wrapped in a form element. When the user enters a city name and clicks the button, we’re calling the handleSubmit function, which in turn calls the fetchWeather function with the new city name. We’ve also added a new state variable named city, which holds the current city name. We’re updating the state variable city when the user changes the input value using handleCityChange function.

Step 9: Summary

In this tutorial, we’ve built a weather app in React using hooks. We started by creating a new React project using create-react-app and then installed the axios package to make API requests. We then created a new component named Weather, and used the useEffect hook to make an API request to OpenWeatherMap API when the component is mounted. We displayed the weather data in the component and added some styling using CSS. Finally, we added an input field and a button to the component, which allows the user to update the city name dynamically. We used the useState hook to store the current city name and used it to make API requests. We used the onChange and onSubmit event handlers to update the state and fetch weather data respectively.

I hope this tutorial was helpful in learning how to build a weather app in React using hooks!

Feel free to check out my work here: