6/6 커스텀훅으로 location정보, weather 정보 가져오기

낄낄박사·2024년 6월 6일

React 훅 사용 시 비동기 작업을 직접 호출하는 방식은 추천되지 않음. 훅 내부에서 상태 업데이트를 안전하게 처리하기 위해 useEffect 훅을 사용하는 것이 좋다.

커스텀훅으로 분리하기

location 정보를 가져올때 useEffect 안에서 데이터를 페칭하는 로직이 반복되어 커스텀훅으로 분리하였음.

복잡한 로직을 필요한 컴포넌트 내에 그대로 주면 컴포넌트가 너무 장황해지고 이해가 어려워질 수도 있음.
또한 해당 로직을 커스텀 훅으로 분리하면 재사용성도 높아지고 코드도 일관되게 관리할 수 있음.
로직을 수정할 때에도 모든 곳을 찾아다닐 필요 없이 커스텀훅으로 분리한 곳 만 수정하면 되니까 유지보수도 당근 쉬워짐.

관심사의 분리

React에서는 컴포넌트가 UI를 관리하고, 훅이 로직을 관리하는 것이 이상적이라 했음.
그러니 커스텀 훅으로 분리하면 컴포넌트는 UI에 집중하고, 훅은 데이터를 처리나 상태관리 등 로직에 집중할 수 있음!!

import axios from "axios";
import { useEffect, useState } from "react";

type Location = {
  lat: number;
  lon: number;
};
export default function useLocation() {
  const [location, setLocation] = useState<Location>({
    lat: 37.566535,
    lon: 126.9779692,
  });
  const [cityName, setCityName] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setGeoError] = useState<string | null>(null);

  const geolocation = navigator.geolocation;

  useEffect(() => {
    if (geolocation) {
      geolocation.getCurrentPosition(
        (position) => {
          const newLocation = {
            lat: position.coords.latitude,
            lon: position.coords.longitude,
          };
          setLocation(newLocation);
          fetchCityName(newLocation.lat, newLocation.lon);
        },
        (error) => console.log(error, "Unable to retrieve your location")
      );
    } else {
      console.log("Geolocation is not supported by your browser");
      setGeoError("Geolocation is not supported by your browser");
    }

    const fetchCityName = async (lat: number, lon: number) => {
      if (lat && lon) {
        try {
          setIsLoading(true);
          const { data } = await axios.get(
            `/api/location?lat=${lat}&lon=${lon}`
          );
          setCityName(data.cityName);
          setIsLoading(false);
        } catch (error) {
          console.log("Error fetching location");
        }
      }
    };
  }, []);

  return { location, cityName, isLoading, error };
}

나중에는 SWR을 사용해서 데이터 페칭하도록 리팩토링 해볼 것임

0개의 댓글