Web-Frontend/React-Native

[RN] CMC 2주차 과제 트러블 슈팅

서노리 2024. 6. 21. 17:19
반응형

2주차 과제: 지도 구현

주요 기능

1. 지도 불러오기: 웹뷰를 이용하여 앱에서 지도를 띄웁니다. ✅

2. 지도 상호 작용: 확대, 축소 및 드래그 이동 기능을 구현합니다. ✅

3. 현재 위치 표시: 사용자의 현재 위치를 지도에 표시합니다. ✅

4. 즐겨찾기 기능: 즐겨찾기 위치를 추가하고, 해당 목록을 관리합니다. ✅

 

시연 영상

폴더 구조

1. app

app
├── assets
|  ├── HomeSvg.tsx
|  ├── StarBtnSvg.tsx
|  ├── StarSvg.tsx
|  └── TrashCanSvg.tsx
├── components
|  ├── BottomNavigator.tsx
|  ├── StackNavigator.tsx
|  └── StarItem.tsx
├── constants
|  └── palette.ts
├── screens
|  ├── Home.tsx
|  └── Stars.tsx
├── store
|  └── store.ts
├── tree.txt
└── types
   ├── declarations.d.ts
   ├── navigation.d.ts
   └── types.d.ts

 

2. web

web
├── App.tsx
├── assets
|  └── StarSvg.tsx
├── components
|  ├── NaverMap.style.ts
|  └── NaverMap.tsx
├── constants
|  └── palette.ts
├── index.css
├── index.tsx
├── store
|  └── store.ts
├── types
   ├── declarations.d.ts
   └── types.d.ts

 

기술 스택

1. app

  • react-native
  • typescript
  • zustand
  • react-native-webview

2. web

  • react
  • typescript
  • styled-components
  • zustand
  • navermaps api

트러블 슈팅

1. 안드로이드 애뮬레이터의 경우 로컬서버에 접근할 때 localhost가 아닌 10.0.0.2로 접근해야한다.

따라서 다음과 같이 분기 처리를 해주어야함.

const localServerURL =
    Platform.OS === 'android'
      ? 'http://10.0.2.2:3000'
      : 'http://localhost:3000';

 

 

2. react-native-webview는 플랫폼별로 메세지 이벤트를 발생시키는 객체가 다르다.

안드로이드의 경우 document 객체, ios의 경우 window 객체에서 message 이벤트를 발생시킨다.

따라서 다음과 같이 분기 처리를 해주어야함.

if (navigator.userAgent.match(/Android/i)) {
  document.addEventListener("message", handleMessage);
} else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
  window.addEventListener("message", handleMessage);
}

 

3. 애뮬레이터를 사용하는 경우 위치 정보를 얻어온다 하더라도 가상 위치를 얻어오게 됨..

4. 네이버 지도 클릭 이벤트 트러블슈팅

useEffect(() => {
    initMap();
    // alert(`위도: ${latitude}, 경도: ${longitude}`);
  }, [latitude, longitude]);

  useEffect(() => {
    if (mapInstance) {
      const handleClick = (e: any) => {
        if (selected) {
          selected.setMap(null);
        }
        const newMarker = new window.naver.maps.Marker({
          position: e.coord,
          map: mapInstance,
        });

        setSelected(newMarker);
      }

      const listener = window.naver.maps.Event.addListener(mapInstance, "click", handleClick);
      return () => {
        window.naver.maps.Event.removeListener(listener);
      };
    }
  }, [selected, mapInstance]);

먼저 이벤트 핸들링 부분을 initMap과 분리해줌. mapInstance를 의존성 배열에 추가해줌으로써 null에서 실제 지도로 초기화된 이후에 이벤트리스너를 추가해줄 수 있도록 했음.또한 selected가 바뀔때마다 이벤트리스너를 재정의 해주어야함.이유는 다음과 같음.

5. npm install @types/navermaps을 통해 네이버지도 api의 타입정보를 얻을 수 있음.

그래도 에러가 난다면 tsconfig.json에 다음과 같이 추가

"types": ["styled-components", "navermaps"]

6. 즐겨찾기 삭제할 때 주소 → 좌표 변환 후 마커 좌표랑 비교해서 마커 삭제 하려했는데, 두 좌표에 약간의 오차가 존재하는 것을 발견 → 좌표 비교가 아닌 아이디 값으로 삭제하도록 로직변경.


반응형

'Web-Frontend > React-Native' 카테고리의 다른 글

[RN] CMC 1주차 과제 - 환경세팅, TODO 앱 구현  (0) 2024.05.31