From f85b32a28c8a968e932f5f1c8359a4f44c15d645 Mon Sep 17 00:00:00 2001 From: techieadi4703 Date: Thu, 16 Oct 2025 16:57:01 +0530 Subject: [PATCH] implement debounced city search to optimize API calls --- src/pages/Weather.jsx | 60 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/pages/Weather.jsx b/src/pages/Weather.jsx index 6a68d52..37e559c 100644 --- a/src/pages/Weather.jsx +++ b/src/pages/Weather.jsx @@ -14,6 +14,7 @@ * - [x] Persist last searched city (localStorage) * - [x] Add error retry button component * - [ ] Add favorites list (pin cities) + * - [x] Optimize API usage by adding debounced search delay * Advanced: * - [ ] Hourly forecast visualization (line / area chart) * - [x] Animate background transitions @@ -65,7 +66,10 @@ function renderWeatherAnimation(variant) { <> - + @@ -105,7 +109,7 @@ function renderWeatherAnimation(variant) { left: `${(i / 12) * 100}%`, animationDelay: `${(i % 6) * 0.4}s`, "--dur": `${10 + (i % 6)}s`, - "--drift": `${(i % 2 === 0 ? -40 : 40)}px`, + "--drift": `${i % 2 === 0 ? -40 : 40}px`, width: `${8 + (i % 3) * 4}px`, height: `${8 + (i % 3) * 4}px`, }} @@ -145,10 +149,20 @@ export default function Weather() { const [activeBg, setActiveBg] = useState("default"); const [prevBg, setPrevBg] = useState(null); + // Fetch data initially useEffect(() => { fetchWeather(city); }, []); + // ✅ Debounced search effect + useEffect(() => { + if (!city.trim()) return; + const handler = setTimeout(() => { + fetchWeather(city); + }, 800); // delay in ms + return () => clearTimeout(handler); + }, [city]); + async function fetchWeather(c) { try { setLoading(true); @@ -256,10 +270,7 @@ export default function Weather() { {loading && } {error && ( - fetchWeather(city)} - /> + fetchWeather(city)} /> )} {data && !loading && ( @@ -290,36 +301,23 @@ export default function Weather() { {/* 3-Day Forecast */} {forecast.map((day, i) => { - const condition = - day.hourly?.[0]?.weatherDesc?.[0]?.value || "Clear"; + const condition = day.hourly?.[0]?.weatherDesc?.[0]?.value || "Clear"; const badge = getBadgeStyle(condition); return ( - {day.hourly?.[0] && - getIconUrl(day.hourly?.[0]?.weatherIconUrl) && ( -
- { - (e.currentTarget.style.display = "none") - } - /> -
- )} + {day.hourly?.[0] && getIconUrl(day.hourly?.[0]?.weatherIconUrl) && ( +
+ {day.hourly?.[0]?.weatherDesc?.[0]?.value (e.currentTarget.style.display = "none")} + /> +
+ )} -
+
Avg Temp:{" "} {displayTemp(Number(day.avgtempC))}°{unit}