
ํํ์ด์ง์ ์ ์ํด ํ์๊ฐ์ /๋ก๊ทธ์ธ์ ํ๋ฉด API KEY๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.

API_KEY๋ฅผ ๋ณต์ฌํ ๋ค์ ํ๋ก์ ํธ์ .env ํ์ผ์ ๋ฑ๋กํฉ๋๋ค.
์ ๋ Vite๋ฅผ ์ฌ์ฉํด ํ๋ก์ ํธ๋ฅผ ์งํ์ค์ด๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ์ต๋๋ค.
//Vite๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํ๊ฒฝ ๋ณ์ ์ด๋ฆ์ `VITE_` ๋ก ์์ํด์ผ ํฉ๋๋ค.
VITE_WEATHER_API_KEY="my_api_key"
//weather widget component์์ importํด์ ์ฌ์ฉํฉ๋๋ค.
const API_KEY = import.meta.env.VITE_WEATHER_API_KEY;
โ๐ป Vite๊ฐ ์๋ ๊ฒฝ์ฐ
// .env REACT_WEATHER_API_KEY="api_key" // weather widget component const API_KEY = prpcess.env.REACT_WEATHER_API_KEY
API ํญ์์ ์ฌ์ฉํ๋ ค๋ Current Weather Data ์ API doc์ ํ์ธํฉ๋๋ค.

ํด๋น API๋ฅผ ๋ถ๋ฌ์ค๋ url์ ํ์ธํ ์ ์์ต๋๋ค.

API url์ ๋ณด๋ฉด lat, lon, API key ์ธ๊ฐ์ง์ ๊ฐ์ ๋ฃ์ด์ผ ํฉ๋๋ค.
API key ์์น์๋ ์์์ ๊ฐ์ ธ์จ API_KEY๋ฅผ ๋ฃ์ด์ค๋๋ค.url์ ๋ฃ์ ์๋์ ๊ฒฝ๋๋ฅผ ์ ์ ์์ ์์น๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๊ธฐ ์ํด ์์น ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
HTML Geolocation API๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ ์ ์์น๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ด๋ฅผ ํ์ฉํด ์ฑ ์คํ์ ์์น๋ฅผ ๊ฐ์ ธ์ค๋๋ก useEffect๋ฅผ ์์ฑํฉ๋๋ค.
useEffect(() => {
// ์ฌ์ฉ์ ์์น ์ ๋ณด๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์ ธ์ค๋ ํจ์
navigator.geolocation.getCurrentPosition((position) => {
// position ๋งค๊ฐ ๋ณ์๋ ํ์ฌ ์์น์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์์ต๋๋ค.
// position์์ ์๋๊ฐ๊ณผ ๊ฒฝ๋๊ฐ์ ๊ตฌํฉ๋๋ค.
const lat = position.coords.latitude;
const lon = position.coords.longitude;
});
}, []); // ์ฑ์ ์ฒ์ ์คํํ ๊ฒฝ์ฐ์๋ง ๋์ํ๋๋ก ํฉ๋๋ค.
์์์ ์ป์ ์ ์๋ lat, lon ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋ ์จ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์ด๋ ์์น์ ๋ณด๋ฅผ ํ์ฉํ์ง ์์ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์์ธํน๋ณ์ ์ค๊ตฌ์ ์๋, ๊ฒฝ๋๋ฅผ ๋ฃ์ด์ค๋๋ค.
const getWeather = async (lat = 37.5641, lon = 126.9970) => {
try {
const res = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`);
const data = res.json()
console.log(data)
} catch (error) {
console.error(error)
}
};
๋ ์จ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์(getWeather())๋ฅผ ์์น ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์ ์์์ lat, lon ๊ฐ์ ์ ๋ฌํ์ฌ ํธ์ถํฉ๋๋ค. console๋ก ๋ ์จ ๋ฐ์ดํฐ๋ฅผ ํ์ธํฉ๋๋ค.
useEffect(() => {
navigator.geolocation.getCurrentPosition((position) => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
getWeather(lat, lon);
});
}, []);
์์ธํ๊ฒ ํ์ธํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
{
"base": "stations", // ๋ด๋ถ ๋งค๊ฐ ๋ณ์
"clouds": {
"all": 0 // ํ๋ฆผ(%)
},
"cod": 200, // ๋ด๋ถ ๋งค๊ฐ๋ณ์
"coord": {
"lon": 126.7298, // ์์น์ ๊ฒฝ๋
"lat": 37.5126 // ์์น์ ์๋
},
"dt": 1718188665, // ๋ฐ์ดํฐ ๊ณ์ฐ ์๊ฐ(unix, UTC)
"id": 1838716, // ๋์id
"main": {
"feels_like": 22.42, // ์จ๋ (๊ธฐ๋ณธ๊ฐ ๋จ์ : ์ผ๋น)
"pressure": 1005, // ํด์๋ฉด์ ๋๊ธฐ์(hPa)
"humidity": 60, // ์ต๋(%)
"temp": 22.54, // ์จ๋ (๊ธฐ๋ณธ๊ฐ ๋จ์: ์ผ๋น)
"temp_min": 20.94, // ์ต์ ๊ธฐ์จ
"temp_max": 27.91, // ์ต๊ณ ๊ธฐ์จ
},
"name": "Bucheon-si", // ๋์์ด๋ฆ
"sys": {
"country": "KR", // ๊ตญ๊ฐ ์ฝ๋
"id": 8105, // ๋ด๋ถ ๋งค๊ฐ๋ณ์
"sunrise": 1718136690, // ์ผ์ถ ์๊ฐ(UTC)
"sunset": 1718189672, // ์ผ๋ชฐ ์๊ฐ(UTC)
"type": 1, // ๋ด๋ถ ๋งค๊ฐ๋ณ์
},
"timezone": 32400, // UTC ์ด๋จ์ ์ด๋
"visibility": 10000, //๊ฐ์์ฑ (๋จ์ m, ์ต๋ 10km)
"weather": [
{
"description": "clear sky", // ๊ทธ๋ฃน ๋ด ๋ ์จ ์ํ
"icon": "01d", // ๋ ์จ ์์ด์ฝ id
"id": 800, // ๊ธฐ์์กฐ๊ฑด id
"main": "Clear", // ๋ ์จ ๋งค๊ฐ๋ณ์ ๊ทธ๋ฃน(๋น, ๋, ๊ตฌ๋ฆ ๋ฑ)
}
],
"wind": {
"deg": 300, // ํํฅ
"speed": 3.6, // ํ์(๊ธฐ๋ณธ๊ฐ ๋จ์ : m/s)
},
}
์ฌ๊ธฐ์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํด์ ์ฌ์ฉํฉ๋๋ค.
์ ๋ name, weather, temp ์ ๋ณด๋ง ์ฌ์ฉํด โํ์ฌ ์์นโ, โ๋ ์จ ์จ๋โ, โ๋ ์จ ์์ด์ฝโ, โ๋ ์จ์ ๋ํ ์ค๋ช
โ์ ํฌํจํ๋ ๊ฐ๋จํ ์์ ฏ์ ๋ง๋ค ๊ฒ ์
๋๋ค. ํ์ํ ์ ๋ณด๋ฅผ state๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด useState๋ฅผ ์ฌ์ฉํฉ๋๋ค.
const [weather, setWeather] = useState({
location: '',
temperature: 0,
weatherIconUrl: undefined,
description: '',
});
๊ทธ ์ค โ๋ ์จ ์์ด์ฝโ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด API doc์ Weather Conditions๋ฅผ ํ์ธํฉ๋๋ค. (์ฌ์ดํธ์์ ์์ด์ฝ ํํ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.)

์ ์ค๋ช
์ ๋ฐ๋ฅด๋ฉด weahter.icon ๊ฐ์ ๋ฃ์ด img url์ ์ป์ ์ ์์ต๋๋ค. url์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const iconUrl = `https://openweathermap.org/img/wn/${weather.icon}@2x.png`;
API doc์ ๋ฐ๋ฅด๋ฉด ๋ ์จ ์ค๋ช
์ ํ๊ธ๋ก ๊ฐ์ ธ์ค๊ธฐ ์ํด API_URL์ lang=kr์ ์ถ๊ฐํ ์ ์๋ค๊ณ ๋์์์ต๋๋ค. ํ์ง๋ง ๋ฒ์ญ์ด ๋ถ์กฑํ์ฌ ๊ตฌ๊ธ๋งํ ๊ฒฐ๊ณผ OpenWeatherMap api ๋ค๊ตญ์ด์ ํ๊ตญ์ด ์ง์์ ์ํ ํ์
์ฉ ํ์ผ์ด๋ผ๊ณ ๋ ์จ ์ฝ๋์ ๋ฐ๋ฅธ ์ ์ ํ ์ค๋ช
์ด ๊ณต์ ๋์ด ์์๊ณ , ์น์ ํ์ ๋ถ๋ค์ด ๋งคํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๊ณต์ ํด ์ฃผ์
จ์ต๋๋ค.(์ ๋ง ๊ฐ์ฌํฉ๋๋ค!)
๋ฐฐ์ด์์ ๊ฐ์ฒด๋ก ๋งคํํ js์ฝ๋๋ ์์ง๋ง, ์ ๋ dart map์ผ๋ก ์์ฑํด์ฃผ์ @b0unt9๋์ ์ฝ๋๋ฅผ js๋ก ์ฌ์ฉํ์ต๋๋ค.
// weatherDescKo.js ํ์ผ์ ๋ฐ๋ก ์ ์
const weatherDescKo = {
201: '๊ฐ๋ฒผ์ด ๋น๋ฅผ ๋๋ฐํ ์ฒ๋ฅ๊ตฌ๋ฆ',
200: '๋น๋ฅผ ๋๋ฐํ ์ฒ๋ฅ๊ตฌ๋ฆ',
...
962: 'ํ๋ฆฌ์ผ์ธ',
};
export default weatherDescKo
weatherWidgetComponent์์ importํด์ ์ฌ์ฉํฉ๋๋ค.
// weatherWidgetComponent
import weatherDescKo from '../weatherDescKo';
const getWeather = async (lat, lon ) => {
try {
...
const location = data.name;
// ์จ๋ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ ๋ฐ์ฌ๋ฆผ ํด์ค๋๋ค.
const temperature = Math.round(data.main.temp);
// icon๋ฒํธ๋ฅผ ๊ฐ์ ธ์ url๋ก ๊ฐ์ ธ์ต๋๋ค.
const weatherIcon = data.weather[0].icon;
const weatherIconUrl = `https://openweathermap.org/img/wn/${weatherIcon}@2x.png`;
// weather_id๋ฅผ ํตํด ๊ฐ์ ธ์จ weatherDescKo์์ id์ ํด๋นํ๋ ์ค๋ช
์ ๊ฐ์ ธ์ต๋๋ค.
const weatherId = data.weather[0].id;
const description = weatherDescKo[weatherId];
// ์ ์ํ ์์ฑ๋ค์ weather state์ ๋ฐ์ํฉ๋๋ค.
setWeather({
location,
temperature,
weatherIconUrl,
description,
});
} catch (err) {
console.log(err);
}
};
return๋ฌธ์์ weather state ๊ฐ์ ์ ์ ํ๊ฒ ๋ฐฐ์นํฉ๋๋ค.
