날씨 데이터가 필요한 각 컴포넌트에서 날씨 데이터를 공유하는 방식과 날씨 호출 함수가 매우 비효율적이라 판단하여 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에서 해주고 데이터를 보내주는 로직으로 변경하겠습니다.