스파르타코딩클럽 내일배움캠프 TIL76

한재창·2023년 2월 15일
0

최종프로젝트

내 위치 가져오기

  • JS에서 제공하는 navigator.geolocation.getCurrentPosition() 메서드를 사용하면 나의 경도, 위도를 알려준다.
  • useState 에 현재 위치를 저장해준다.
  • 가져오는데 2~3초 정도 걸리는데 default 값을 넣어주는게 좋을지 고민된다.
 const getLocation = (): Promise<GeolocationPosition> => {
    return new Promise((resolve, reject) => {
      if (navigator.geolocation) {
        // getCurrentPosition 사용자의 경도, 위도를 알려줌
        // 첫 번째 인자가 성공했을 때 반환하는 함수, 두 번째 인자가 실패했을 때 반환하는 함수
        navigator.geolocation.getCurrentPosition(
          (position) => {
            if (position) {
              console.log(position);
              setMyLocation({
                Ma: position.coords.latitude,
                La: position.coords.longitude,
              });
            }
          },
          (error) => reject(error),
        );
      } else {
        alert('Geolocation is not supported by this browser.');
      }
    });
  };

  console.log(myLocation);
  useEffect(() => {
    getLocation();
  }, [map]);

검색하면 지도에서 위치 이동

  • 키워드로 검색할 때 지도가 이동하는데 이동한 위치에서 map.getCenter() 메서드를 사용하면 현재 지도 위치의 중앙 경도, 위도 값을 가져올 수 있다.
  • 키워드를 검색할 때 마다 myLocation 을 set 해서 지도의 중앙값이 현재 위치로 설정하게 하였다.
 const setMakerHandler = () => {
 		let latlng = map.getCenter();
        setMyLocation(latlng);
          }
  • 맵의 중앙에 myLocation 의 경도, 위도 값을 설정해주었다.
  • 맵의 중앙에 나의 위치를 알려주는 마커표시를 해주었다.
  {/* 맵이 맨 처음 렌더링 되면 getLocation에서 내 위치를 가져온 값이 center 기준이 되고 marker도 center 좌표에 찍힌다.
      검색하고 onSubmit이 발생되면 map.getCenter() 메서드로 myLocation의 값을 검색 기준 지도 가운데 경도, 위도로 바꿔준다.
      map.getCenter() 함수를 몰라서 오래 걸렸다 후... */}
      <Wrap // 로드뷰를 표시할 Container
        center={{
          lat: (myLocation && myLocation?.Ma) || 0,
          lng: (myLocation && myLocation?.La) || 0,
        }}
        level={3}
        onCreate={setMap}
      >
        <MapMarker // 마커를 생성합니다
          position={{
            // 마커가 표시될 위치입니다
            lat: myLocation?.Ma || 0,
            lng: myLocation?.La || 0,
          }}
        />

내 위치에 따른 날씨 가져오기

  • 디테일 페이지에서 한 것과 코드가 거의 똑같다.
  • 다른점은 인자로 넘겨주는 lat, lon 값을 현재의 경도, 위도 값으로 변경해주었다.
  • useQuery 에서 refetch() 라는 함수를 제공해준다.
  • useEffect() 를 이용해서 myLocation 의 값이 바뀔 때만 리액트 쿼리가 다시 데이터를 fetch 해오도록 설정하였다.
    💡 리액트 쿼리를 더 공부해야겠다@!@!@!!@!@!@!@!!
import styled from 'styled-components';
import { useQuery } from 'react-query';
import {
  getDetailAirPollutionData,
  getDetailWeatherData,
} from '../../../services/api';
import { useEffect } from 'react';

const API_KEY = '45fabc77306799b105d9b9f9d05ad05a';

interface airPollutionChangeTheText {
  [key: string]: string | number;
}
interface Props {
  myLocation: any;
}

const MapWeather = ({ myLocation }: Props) => {
  const queryProps = {
    lat: myLocation?.Ma || 0,
    lon: myLocation?.La || 0,
    api: API_KEY,
  };

  // 날씨 데이터 가져오는 함수

  const { data: weatherData, refetch: weatherRefetch } = useQuery(
    'weather',
    () => getDetailWeatherData(queryProps),
  );

  // 미세먼지 데이터 가져오는 함수
  const { data: airPollutionData, refetch: airPollutionRefetch } = useQuery(
    'airpollution',
    () => getDetailAirPollutionData(queryProps),
  );

  useEffect(() => {
    weatherRefetch();
    airPollutionRefetch();
  }, [myLocation]);

  // 미세먼지가 숫자로 표시되어 문자로 변환하기 위한 상수
  const airPollutionChangeTheText: airPollutionChangeTheText = {
    1: '매우 좋음',
    2: '좋음',
    3: '보통',
    4: '나쁨',
    5: '매우 나쁨',
  };

  return (
    <Wrap>
      <WeatherWrap>
        <WeatherText>날씨 : {weatherData?.weather[0]?.main}</WeatherText>
        <WeatherText>기온 : {weatherData?.main?.temp}</WeatherText>
        <WeatherText>
          미세먼지 :{' '}
          {airPollutionChangeTheText[airPollutionData?.list[0]?.main?.aqi]}
        </WeatherText>
      </WeatherWrap>
    </Wrap>
  );
};

export default MapWeather;

const Wrap = styled.div`
  display: flex;
  justify-content: flex-end;
`;
const WeatherWrap = styled.div`
  width: 300px;
  display: flex;
  justify-content: space-between;
`;
const WeatherText = styled.span``;
profile
취준 개발자

0개의 댓글