느려도 한걸음씩

React로 HTTP 요청 보내기 - (5) 본문

FE develop/React

React로 HTTP 요청 보내기 - (5)

hoj0806 2025. 3. 12. 13:58

 

fetch된 데이터를 변환시켜 사용해보자

 

function toRad(value) {
  return (value * Math.PI) / 180;
}

function calculateDistance(lat1, lng1, lat2, lng2) {
  const R = 6371;
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lng2 - lng1);
  const l1 = toRad(lat1);
  const l2 = toRad(lat2);

  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(l1) * Math.cos(l2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  const d = R * c;
  return d;
}

export function sortPlacesByDistance(places, lat, lon) {
  const sortedPlaces = [...places];
  sortedPlaces.sort((a, b) => {
    const distanceA = calculateDistance(lat, lon, a.lat, a.lon);
    const distanceB = calculateDistance(lat, lon, b.lat, b.lon);
    return distanceA - distanceB;
  });
  return sortedPlaces;
}

places 데이터와 사용자의 현재 위치를 매개변수로 받아 사용자의 위치와 가까운순으로 위치를 정렬하는 함수이다

 

    navigator.geolocation.getCurrentPosition((position) => {
          const sortedPlaces = sortPlacesByDistance(
            resData.places,
            position.coords.latitude,
            position.coords.longitude
          );
        });

 

try 문안에  navigator.geolocation.getCurrentPosition 메서드를 이용해 position 객체를 사용할수 있다 이 position 객체를 통해 사용자가 현재 위치한 위도와 경도를 알아낼수 있다 매개변수로 패칭된 places 데이터 , 위도, 경도를 순서대로 넣어준다

 

  navigator.geolocation.getCurrentPosition((position) => {
          const sortedPlaces = sortPlacesByDistance(
            resData.places,
            position.coords.latitude,
            position.coords.longitude
          );
          setAvailablePlaces(sortedPlaces);
        });

그리고 정렬된 데이터를 availablePlaces state에 넣어주면 된다

 

이렇듯 패칭된 데이터는 얼마든지 변환시켜 사용할수 있다

 

이때 조심해야할건 navigator.geolocation.getCurrentPosition의 콜백에서도 setIsFetching(false);를 호출해줘야 한다

 

위치 정보를 가져오는 것도 비동기 작업이므로, 위치 정보를 받은 후에 false로 변경해야한다 

 

  useEffect(() => {
    async function fetchPlaces() {
      setIsFetching(true);

      try {
        const response = await fetch("http://localhost:5000/places");
        const resData = await response.json();
        if (!response.ok) {
          throw new Error("Failed to fetch");
        }
        navigator.geolocation.getCurrentPosition((position) => {
          const sortedPlaces = sortPlacesByDistance(
            resData.places,
            position.coords.latitude,
            position.coords.longitude
          );
          setAvailablePlaces(sortedPlaces);
          setIsFetching(false); // 위치 정보를 받은 후 로딩 상태 해제
        });
      } catch (error) {
        setError({ message: error.message });
        setIsFetching(false); // 요청이 실패했을 경우 로딩 상태 해제
      }
    }

    fetchPlaces();
  }, []);