피드관리 - Part 1 피드작성 (2) 장소 및 날씨 입력
ㆍProject Diary/React + MariaDB (PicShare WebApp)
사용자가 피드 작성 시 현재 위치나 입력한 장소의 날씨 정보를 가져오고, 이를 바탕으로 해시태그를 추천하는 기능을 구현합니다. 이 글에서는 날씨 API를 사용하여 위치와 날씨 정보를 가져오고, 이를 활용해 피드에 정보를 입력하는 과정을 다룹니다.
데이터베이스
- locationName : 위치 이름
- weatherInfo : 날씨 정보 (JSON)
- weathericon : 날씨 아이콘
프론트엔드
1. 장소 및 날씨 입력 기능
1-1 날씨 API를 사용하여 위치에 따른 날씨 정보를 가져오는 함수
const getWeatherByCoords = async (lat, lon) => {
const response = await axios.get(
`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
);
return response.data;
};
const getWeatherByLocationName = async (locationName) => {
const response = await axios.get(
`https://api.openweathermap.org/data/2.5/weather?q=${locationName}&appid=${API_KEY}&units=metric`
);
return response.data;
};
const getLocationNameByCoords = async (lat, lon) => {
const response = await axios.get(
`http://api.openweathermap.org/geo/1.0/reverse?lat=${lat}&lon=${lon}&limit=1&appid=${API_KEY}`
);
return response.data[0].name;
};
- getWeatherByCoords : 위도와 경도로 날씨 정보를 가져옵니다.
- getWeatherByLocationName : 장소 이름으로 날씨 정보를 가져옵니다.
- getLocationNameByCoords : 위도와 경도로 장소 이름을 가져옵니다.
1-2 컴포넌트가 마운트될 때 현재 위치의 날씨와 장소 정보를 가져옴
useEffect(() => {
navigator.geolocation.getCurrentPosition(async (position) => {
const { latitude, longitude } = position.coords;
setLatitude(latitude);
setLongitude(longitude);
const weatherData = await getWeatherByCoords(latitude, longitude);
setWeather(weatherData);
const locName = await getLocationNameByCoords(latitude, longitude);
setLocationName(locName);
fetchRecommendedHashtags(weatherData.weather[0].main.toLowerCase());
});
}, []);
컴포넌트가 마운트될 때 사용자의 현재 위치를 가져오고, 해당 위치의 날씨 정보를 가져옵니다.
1-3 장소 이름으로 날씨 정보 가져오기
const handleGetWeatherByLocation = async () => {
try {
const weatherData = await getWeatherByLocationName(locationName);
setLatitude(weatherData.coord.lat);
setLongitude(weatherData.coord.lon);
setWeather(weatherData);
fetchRecommendedHashtags(weatherData.weather[0].main.toLowerCase());
} catch (err) {
console.error("Failed to fetch weather data:", err);
alert("날씨 정보를 가져오는데 실패했습니다. 장소 이름을 확인해주세요.");
}
};
1-4 위치 및 날씨 정보 입력 UI
<div className="location-section">
<div className="checkbox-label">
<p>위치와 날씨 정보를 게시하시겠습니까?</p>
<label>
<input
type="checkbox"
checked={showWeatherInfo}
onChange={() => setShowWeatherInfo(!showWeatherInfo)}
/>
<span style={{ color: "#09fc52", fontWeight: "bold" }}>
위치 및 날씨 정보 게시
</span>
</label>
</div>
{showWeatherInfo && (
<>
<div className="weatherinputfield">
<div className="infowrap">
<p className="locationinfo">
<MdPlace /> {locationName}
</p>
<div>
<div className="weatherinfo">
{weather && (
<>
<img
src={`https://openweathermap.org/img/wn/${weather.weather[0].icon}.png`}
alt={weather.weather[0].description}
/>
<p>{weather.main.temp}°C</p>
</>
)}
</div>
<p>{weather && weather.weather[0].description}</p>
</div>
</div>
<div className="inputwrap">
<div className="locationinput">
<input
type="text"
placeholder="장소 이름을 입력하세요..."
value={locationName}
onChange={handleLocationChange}
/>
<button type="button" onClick={handleGetWeatherByLocation}>
날씨 정보 가져오기
</button>
</div>
<span>
* 현재 위치를 자동으로 불러오거나 직접 입력할 수 있습니다.
</span>
</div>
</div>
{weather && (
<div>
<div
className="recommended-hashtags"
style={{
border: "none",
display: "flex",
alignItems: "center",
}}
>
<p>이런 해시태그는 어떠세요?</p>
{recommendedHashtags.map((hashtag, idx) => (
<button
key={idx}
type="button"
onClick={() => handleRecommendedHashtagClick(hashtag)}
style={{
fontSize: "15px",
margin: "0 5px",
background: "#fff",
border: "1px solid #ccc",
borderRadius: "5px",
padding: "5px 10px",
color: "#aaa",
alignItems: "center",
fontWeight: "bold",
}}
>
#{hashtag}
</button>
))}
</div>
</div>
)}
</>
)}
</div>
사용자가 위치와 날씨 정보를 입력하고, 해당 정보를 기반으로 추천 해시태그를 받을 수 있게 합니다.
1-5 장소 및 날씨 정보 제출
formData.append("weathericon", weather ? weather.weather[0].icon : null);
위치 및 날씨 정보를 formData에 추가하여 서버로 전송합니다.