Share
Explore

The Weather App

What you will build:

A Weather app with web pack instructions and html page.

table summarizing, comparing, and contrasting the useState and useEffect hooks in React:

what is the difference between useState and useEffect


useState and useEffect are both hooks in React that were introduced in version 16.8.
They serve different purposes:
useState is used to add state to functional components. It returns a stateful value and a function to update that value. Whenever the state is updated, React will re-render the component and update the UI.
useEffect is used to add side effects to functional components. It allows you to perform side effects, such as fetching data, updating the DOM, or subscribing to events. The useEffect hook takes two arguments: a function to perform the side effect, and an optional array of dependencies. The function will run after the component has rendered, and it will run again whenever any of the dependencies change.

In summary, useState is used to manage state within a component, while useEffect is used to perform side effects that can affect the component or the outside world.
Table 1
Hook
Summary
Usage
1
useState
A hook that allows functional components to have stateful behavior.
const [state, setState] = useState(initialState);
2
useEffect
A hook that allows side effects to be performed in functional components.
useEffect(() => { /* effect code */ }, [dependency]);
3
Comparison
4
State management
useState is used for managing stateful data within a functional component.
N/A
5
Side effect management
useEffect is used for performing side effects in functional components, such as fetching data, subscribing to events, or manipulating the DOM.
N/A
6
Contrast
7
Usage
useState is used within a functional component to define and manage state.
useEffect is used within a functional component to define and manage side effects.
8
Parameters
useState accepts one parameter, the initial state value. It returns an array containing the current state value and a function to update that value.
useEffect accepts two parameters: a function containing the side effect code, and an optional array of dependencies that determine when the effect should be re-run.
9
State updates
State updates using useState replace the current state with a new state value.
State updates within an effect can be performed with setState or by manipulating external state.
10
Side effect dependencies
useState does not have dependencies.
useEffect can have dependencies, which determine when the effect should be re-run.
11
Execution order
useState is executed during rendering, before the return statement.
useEffect is executed after the first rendering and after every re-rendering that depends on its dependencies.
12
Cleaning up
useState does not require any cleanup.
useEffect can return a cleanup function, which is called before the effect is re-run or before the component unmounts.
There are no rows in this table
Before we begin, it's important to note that in order to build a weather app, you'll need to have a weather API key.
You can obtain a key from various weather APIs such as OpenWeatherMap or Weatherbit.
Once you have obtained a key, you can use it to make API calls and fetch weather data for your app.
Now, let's get started with building a weather app using webpack!

Step 1: Set up your project

Create a new directory for your project and initialize a new npm project:
mkdir weather-app
cd weather-app
npm init -y

Step 2: Install dependencies

Next, install the following dependencies:
npm install react react-dom
npm install -D webpack webpack-cli html-webpack-plugin babel-loader @babel/core @babel/preset-env @babel/preset-react style-loader css-loader


Here's what each of these dependencies does:
react and react-dom are the core libraries for building React apps.
webpack and webpack-cli are the core tools for bundling your app.
html-webpack-plugin generates an HTML file that includes a reference to your bundled JavaScript file.
babel-loader, @babel/core, @babel/preset-env, and @babel/preset-react allow you to use modern JavaScript and JSX syntax in your app.
style-loader and css-loader allow you to import and use CSS files in your app.

Step 3: Create your React app

Create a new file called index.js in the root of your project, and add the following code:
import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
};

ReactDOM.render(<App />, document.getElementById('root'));


This code defines a simple React component called App, which renders a div with a h1 element inside. It then renders this component to the root element in the HTM

Step 4: Configure webpack

Create a new file called webpack.config.js in the root of your project, and add the following code:
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './index.js',
output: {
path: __dirname + '/dist',
filename: 'main.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html',
}),
],
devServer: {
contentBase: './dist',
port: 3000,
},
};


This code sets up the entry point for your app, which in this case is index.js. It also specifies the output directory for the bundled app, and the file name (main.js). The module section defines the rules to handle different file types, such as JavaScript and CSS files. Finally, the plugins section sets up the HtmlWebpackPlugin, which generates an HTML file that references the bundled JavaScript code.

Step 5: Create your HTML file

Create a new directory called public in the root of your project, and create a new file called index.html inside it. Add the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Weather App</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/main.js"></script>
</body>
</html>

This HTML file sets up the basic structure of the page, including a title, and a div element with an id of root, which is where the React app will be rendered.

Step 6: Update package.json

Update the scripts section of your package.json file to include the following commands:
"scripts": {
"start": "webpack serve --mode development",
"build": "webpack --mode production"
},
These commands will start the development server and build the production bundle respectively.

Step 7: Start the development server

To start the development server, run the following command in your terminal:
npm start

This will start the server at http://localhost:3000.

Step 8: Build the production bundle

To build the production bundle, run the following command in your terminal:
npm run build

This will create a bundled JavaScript file called main.js in a directory called dist.

Step 9: Fetch weather data

To fetch weather data for your app, you can use the fetch API to make API calls to a weather API. Here's an example of how to fetch weather data using the OpenWeatherMap API:
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`)
.then(response => response.json())
.then(data => {
// handle weather data
})
.catch(error => {
// handle error
});


Replace city with the name of the city you want to fetch weather data for, and apiKey with your own API key.

Step 10: Display weather data in your app

To display weather data in your app, you can update the App component to render weather data based on the data fetched from the weather API. Here's an example of how to display the temperature and weather description:

import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

const App = () => {
const [weatherData, setWeatherData] = useState(null);

useEffect(() => {
const fetchWeatherData = async () => {
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=London&appid=${apiKey}&units=metric`);
const data = await response.json();
setWeatherData(data);
};

fetchWeatherData();
}, []);

return (
<div>
<h1>Weather App</h1>
{weatherData && (
<div>
<p>Temperature: {weatherData.main.temp}°C</p>
<p>Description: {weatherData.weather[0].description}</p>
</div>
)}
</div>
);
};

ReactDOM.render(<App />, document.getElementById('root'));

This code uses the useState and useEffect hooks to fetch weather data from the OpenWeatherMap API and store it in the weatherData state.
It then conditionally renders the temperature and weather description based on whether weatherData is available.
And that's it! With webpack, you can easily bundle your React app for production and start serving it to users. With the OpenWeatherMap API, you can fetch weather data for any city in the world and display it in your app.

HTML page that includes a form with a dropdown to select the city for weather reporting:

<!DOCTYPE html>
<html>
<head>
<title>Weather App</title>
</head>
<body>
<h1>Weather App</h1>
<form>
<label for="city">Select a city:</label>
<select id="city" name="city">
<option value="London">London</option>
<option value="New York">New York</option>
<option value="Paris">Paris</option>
<option value="Tokyo">Tokyo</option>
<option value="Sydney">Sydney</option>
</select>
<button type="submit">Get Weather</button>
</form>
<div id="weather-data"></div>
<script src="bundle.js"></script>
</body>
</html>



This code adds a form element with a select dropdown to select a city and a button to submit the form. When the form is submitted, it will trigger a function in your React app to fetch weather data for the selected city and display it in the weather-data element.


To handle the form submission in your React app, you can update the App component to add a handleSubmit function and pass it to the form element as a prop:


import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const App = () => {
const [weatherData, setWeatherData] = useState(null);

const handleSubmit = async (event) => {
event.preventDefault();
const city = event.target.city.value;
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`);
const data = await response.json();
setWeatherData(data);
};

return (
<div>
<h1>Weather App</h1>
<form onSubmit={handleSubmit}>
<label htmlFor="city">Select a city:</label>
<select id="city" name="city">
<option value="London">London</option>
<option value="New York">New York</option>
<option value="Paris">Paris</option>
<option value="Tokyo">Tokyo</option>
<option value="Sydney">Sydney</option>
</select>
<button type="submit">Get Weather</button>
</form>
{weatherData && (
<div>
<p>Temperature: {weatherData.main.temp}°C</p>
<p>Description: {weatherData.weather[0].description}</p>
</div>
)}
</div>
);
};

ReactDOM.render(<App />, document.getElementById('root'));



This code adds a handleSubmit function that fetches weather data for the selected city and updates the weatherData state. It also passes this function to the form element as a prop, which will be called when the form is submitted. When weatherData is available, it will conditionally render the temperature and weather description.


With this updated HTML page and React app, users can now select a city from the dropdown and get weather data for that city.
To extend the HTML page so it renders out the returned weather query results, we can make use of the weatherData state that we set up earlier in the App component. We can conditionally render the temperature and weather description based on whether weatherData is truthy or not.

Here's the updated code that includes the rendering of the weather data:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const App = () => {
const [city, setCity] = useState('London');
const [weatherData, setWeatherData] = useState(null);

const handleSubmit = async (e) => {
e.preventDefault();
const apiKey = process.env.REACT_APP_WEATHER_API_KEY;
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`);
const data = await response.json();
setWeatherData(data);
};

return (
<div>
<h1>Weather App</h1>
<form onSubmit={handleSubmit}>
<label htmlFor="city">Select a city:</label>
<select id="city" name="city" value={city} onChange={(e) => setCity(e.target.value)}>
<option value="London">London</option>
<option value="New York">New York</option>
<option value="Paris">Paris</option>
<option value="Tokyo">Tokyo</option>
<option value="Sydney">Sydney</option>
</select>
<button type="submit">Get Weather</button>
</form>
{weatherData && (
<div>
<p>Temperature: {weatherData.main.temp}°C</p>
<p>Description: {weatherData.weather[0].description}</p>
</div>
)}
</div>
);
};

ReactDOM.render(<App />, document.getElementById('root'));

In this updated code, we've added a div that conditionally renders the temperature and weather description based on whether weatherData is truthy or not. If weatherData is truthy, it will render a p element with the temperature and another p element with the weather description. If weatherData is falsy, nothing will be rendered
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.