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 |
---|