Building our Weather App One Component at a time
Build the App One Component at a Time
Step 1: App.js — The Main Brain
Open src/App.js and replace its contents with the following:
import React, { useState } from 'react';
import './App.css';
import { getWeatherByCity } from './api/WeatherService';
import SearchBar from './components/SearchBar';
import WeatherCard from './components/WeatherCard';
import TimeDisplay from './components/TimeDisplay';
function App() {
const [weatherData, setWeatherData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const handleSearch = async (city) => {
if (!city) return;
setLoading(true);
setError('');
setWeatherData(null);
try {
const data = await getWeatherByCity(city);
setWeatherData(data);
} catch {
setError('City not found. Please try another one.');
} finally {
setLoading(false);
}
};
return (
<div className="App">
<h1>React Weather App</h1>
<TimeDisplay />
<SearchBar onSearch={handleSearch} />
{loading && <p>Loading...</p>}
{error && <p className="error">{error}</p>}
{weatherData && <WeatherCard data={weatherData} />}
<footer>
Made by <a href="https://www.guvi.in" target="_blank" rel="noreferrer">Jaishree Tomar for GUVI</a>
</footer>
</div>
);
}
export default App;Step 2: WeatherService.js — Talk to the API
Create a file inside src/api/WeatherService.js and paste:
const API_KEY = 'b02928db49861b163d51b3cd51120419';
const BASE_URL = 'https://api.openweathermap.org/data/2.5/weather';
export const getWeatherByCity = async (city) => {
const response = await fetch(`${BASE_URL}?q=${city}&appid=${API_KEY}&units=metric`);
if (!response.ok) {
throw new Error('City not found');
}
return await response.json();
};This fetches data from OpenWeatherMap using a city name.
Don’t forget: Replace the API key if you generate your own at openweathermap.org.
Step 3: SearchBar.js — Let Users Type a City
Inside src/components/SearchBar.js, paste:
import React, { useState } from 'react';
const SearchBar = ({ onSearch }) => {
const [city, setCity] = useState('');
const handleKeyPress = (e) => {
if (e.key === 'Enter') onSearch(city);
};
return (
<div className="search-bar">
<input
type="text"
placeholder="Enter city"
value={city}
onChange={(e) => setCity(e.target.value)}
onKeyPress={handleKeyPress}
/>
<button onClick={() => onSearch(city)}>Search</button>
</div>
);
};
export default SearchBar;Now the user can type a city and press enter or click the search button.
Step 4: WeatherCard.js — Display Weather
Inside src/components/WeatherCard.js, paste:
import React from 'react';
import './WeatherCard.css';
const WeatherCard = ({ data }) => {
const { name, main, weather, wind } = data;
return (
<div className="weather-card">
<h2>{name}</h2>
<img src={`https://openweathermap.org/img/wn/${weather[0].icon}@4x.png`} alt={weather[0].description} />
<p>{weather[0].main} - {weather[0].description}</p>
<p>🌡 Temp: {main.temp} °C</p>
<p>💧 Humidity: {main.humidity}%</p>
<p>🌬 Wind: {wind.speed} m/s</p>
</div>
);
};
export default WeatherCard;Step 5:
Create a CSS file: src/components/WeatherCard.css
.weather-card {
background-color: #1c1c1c;
padding: 2rem;
margin-top: 2rem;
border-radius: 12px;
animation: fadeIn 1s ease-in-out;
}
.weather-card img {
width: 100px;
animation: float 2s infinite ease-in-out;
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
}Step 5: TimeDisplay.js — Show Real-Time Clock
Inside src/components/TimeDisplay.js, paste:
import React, { useState, useEffect } from 'react';
const TimeDisplay = () => {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const interval = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => clearInterval(interval);
}, []);
return <p className="time-display">Current Time: {time}</p>;
};
export default TimeDisplay;

