Loading lessons...
Project 2: Weather Dashboard
Project 2: Weather Dashboard
In this project, you will build a dynamic Weather Dashboard that fetches real-time weather data from an API based on user search queries, incorporating useState, useEffect, and error handling.
Project Specifications
Your application will:
- Allow users to search for cities.
- Fetch weather data inside
useEffectwith loading & error feedback. - Display temperature, humidity, and weather condition badges.
import { useState, useEffect } from 'react';
export default function WeatherDashboard() {
const [city, setCity] = useState('London');
const [search, setSearch] = useState('London');
const [weather, setWeather] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
let active = true;
async function fetchWeather() {
try {
setLoading(true);
setError(null);
// Simulated weather API endpoint response
const res = await fetch("https://api.weatherapi.com/v1/current.json?q=" + city);
if (!res.ok) throw new Error("City not found");
const data = await res.json();
if (active) {
setWeather({
temp: data.current ? data.current.temp_c : 22,
condition: data.current ? data.current.condition.text : "Sunny",
humidity: data.current ? data.current.humidity : 55
});
}
} catch (err) {
if (active) setError(err.message);
} finally {
if (active) setLoading(false);
}
}
fetchWeather();
return () => { active = false; };
}, [city]);
const handleSearchSubmit = (e) => {
e.preventDefault();
if (search.trim()) setCity(search);
};
return (
<div className="weather-dashboard">
<h2>Weather Dashboard</h2>
<form onSubmit={handleSearchSubmit}>
<input
type="text"
value={search}
onChange={e => setSearch(e.target.value)}
placeholder="Enter city..."
/>
<button type="submit">Search Weather</button>
</form>
{loading && <div className="loader">Fetching weather data...</div>}
{error && <div className="error-alert">Error: {error}</div>}
{!loading && !error && weather && (
<div className="weather-card">
<h3>Weather in {city}</h3>
<p className="temp">{weather.temp}°C</p>
<p>Condition: <strong>{weather.condition}</strong></p>
<p>Humidity: {weather.humidity}%</p>
</div>
)}
</div>
);
}
Summary & TL;DR
- Combines search form state with useEffect data fetching.
- Implements robust state management for data, loading, and error feedback.
- Uses cleanup flags to prevent setting state on unmounted components.