날씨 데이터가 필요한 각 컴포넌트에서 날씨 데이터를 공유하는 방식과 날씨 호출 함수가 매우 비효율적이라 판단하여 Context API의 Provider를 이용해 날씨 데이터 공유 로직 및 함수를 개선하겠습니다.
기존 날씨 데이터 호출 함수
const getLocation = async () => {
try {
const position = await new Promise<GeolocationPosition>(
(resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject)
},
)
const latitude = position.coords.latitude
// 위도
const longitude = position.coords.longitude
// 경도
const weatherResponse = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`,
)
const weatherData = await weatherResponse.json()
setTemp(weatherData.main.temp.toFixed(1))
setTempMax(weatherData.main.temp_max.toFixed(1))
setTempMin(weatherData.main.temp_min.toFixed(1))
setIcon(weatherData.weather[0].icon)
const addressResponse = await fetch(
`https://dapi.kakao.com/v2/local/geo/coord2address.json?x=${longitude}&y=${latitude}`,
{
method: 'GET',
headers: { Authorization: `KakaoAK ${KAKAO_API_KEY}` },
},
)
const addressData = await addressResponse.json()
setAddress(
addressData.documents[0].address.region_1depth_name +
' ' +
addressData.documents[0].address.region_2depth_name,
)
// console.log(address);
} catch (error) {
console.error('Error getting location:', error)
}
}
함수 하나에서 현재 위치 정보 불러오기 → 날씨 불러오기 → 현재 위치 불러오기 를 모두 실행하기 때문에 코드의 가독성이 떨어지고 비효율적입니다.
각 과정을 나누어 개별 함수에 담겠습니다.
현재 위치를 가져옵니다.
useEffect(() => {
const getLocation = async () => {
try {
// 위치 노출이 허용되어 있는지 확인하고 현재 위치 가져오기
const position = await new Promise<GeolocationPosition>(
(resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject)
},
)
// 위도와 경도 가져오기
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude)
} catch (error) {
console.error('Error getting location:', error)
}
getLocation();
}
위도와 경도에 값이 닮겼을때, 위치 기반 날씨를 불러옵니다.
useEffect(() => {
const getWeather = async () => {
try {
// OpenWeatherMap에서 위치 기반 날씨 정보 불러오기
const weatherResponse = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude_state}&lon=${longitude_state}&appid=${API_KEY}&units=metric`,
)
const weatherData = await weatherResponse.json()
// 날씨 정보 저장하기
setIcon(weatherData.weather[0].icon)
setWeather(weatherData.weather[0].main)
setTemp(weatherData.main.temp.toFixed(1))
setTempMax(weatherData.main.temp_max.toFixed(1))
setTempMin(weatherData.main.temp_min.toFixed(1))
} catch (error) {
console.error('Error getting location:', error)
}
}
마지막에 값이 들어가는 최저온도에 값이 들어갈 경우 현재 위치를 불러와줍니다.
useEffect(() => {
const getAddress = async () => {
try {
const addressResponse = await fetch(
`https://dapi.kakao.com/v2/local/geo/coord2address.json?x=${longitude_state}&y=${latitude_state}`,
{
method: 'GET',
headers: { Authorization: `KakaoAK ${KAKAO_API_KEY}` },
},
)
const addressData = await addressResponse.json()
setAddress(
addressData.documents[0].address.region_1depth_name +
' ' +
addressData.documents[0].address.region_2depth_name,
)
} catch (error) {
console.error('Error getting location:', error)
}
}
if (address) getAddress()
}, [temperatureMin])
그리고 이 과정을 앞으로 만들 Provider에서 해주고 데이터를 보내주는 로직으로 변경하겠습니다.