추석연휴가 지나고, 오늘도 열심히 프로젝트를 진행했다. 물론 추석연휴 동안에도 열심히 코드를 짜서 기능을 구현했기 때문에 프로젝트의 필수 기능은 이미 다 구현했다. 내가 맡은 부분은 메인페이지와 게시글 추가/수정 페이지의 지도인데, 특히 지도 API를 다루는 게 힘들었다.
먼저 메인페이지를 살펴보자면, 아래와 같다. 헤더, 상단스크롤버튼, 게시글 추가 버튼, 탭으로 게시글 필터링하기, 카드 클릭하면 상세페이지로 넘어가기 같은 기능들을 넣었고, 약간 어려웠던 건 탭으로 게시글 필터링하기였다.
사실 이건 어려웠다기보다는 swtich문이 너무 길어져서 이게 맞나 하는 생각이 들었던 것과, 현재의 데이터베이스 구조로는 이러한 탭과 함께 무한스크롤 기능을 넣을 수 없었던 것이 주요한 고민이었다. switch문이 긴 것은 그렇다 치더라도 무한스크롤 기능은 좀 생각해볼 문제였는데, 한 번쯤은 구현해보고 싶은 기능이었던데다가 명시되어 있는 도전과제이기 때문에 달성해두는 게 좋을 것 같다는 생각이 들었기 때문이다.
일단 어째서 무한스크롤 기능과 db.json의 구조가 관련이 있느냐고 한다면, 지역필터링 기능 때문이다. 우리팀이 현재 사용하는 백엔드 데이터베이스인 jsonserver는 =과 같은 일치하는 값을 가진 데이터들을 가져오게 할 수 있지만 includes와 같은 일부가 포함된 값을 가진 데이터들을 가져오게 할 수는 없다.
이렇게 값을 불러올 수 있지만
http://localhost:4000/posts?foodType=한식
이렇게 값을 불러올 수는 없다
http://localhost:4000/posts?address.includes(서울)
이러한 특성 때문에 지역 필터링 탭을 누를 때마다 axios로 원하는 데이터만을 불러오는 것이 불가능하다. 순수하게 탭 기능만을 구현하려면 지금과 같이 axios로 전부 다 불러온 이후에 filter하는 방법이 있지만, 이러한 방법으로 무한스크롤 기능을 구현하는 것은 의미가 없기 때문에 잠깐 기능을 포기했었다. 그러나 곰곰이 생각해보니 현재 기본적인 기능은 다 만든 상태이고 다들 추가기능을 하는 시점이니 db구조를 좀 바꿔서 무한스크롤 기능을 만들자고 하는 것도 말해볼 법 하다는 생각이 들었다. 현재 무한스크롤 기능을 구현할 수 없는 것은 db구조를 바꾸어서 =로 데이터를 가져올 수 있도록 하면 해결될 수 있다.
이렇게 불러오고
http://localhost:4000/posts?foodType=한식
이렇게 불러오면 된다
http://localhost:4000/posts?local=서울
그리고 아마 최종적으로 이렇게 불러와서 무한 스크롤 기능을 구현해야 할 것이다
http://localhost:4000/posts?foodType=${currentTab}&local=${localTab}&_limit=10
때문에 오후 스크럼 시간 직전에 무한스크롤 기능을 위해서 db.json에 데이터를 추가하는 것을 건의했고, 받아들여져서 아마 내일에는 무한스크롤 기능을 구현해볼 수 있을 것 같다.
그리고 연휴 동안 열심히 구현한 지도API 컴포넌트를 소개하겠다. 코드는 다음과 같고, 지도 생성, 마커 생성, 키워드 검색, 마커 클릭, 마커 이동의 단계로 나누어 볼 수 있다. 이 중 중요한 것은 검색과 클릭 이벤트로, 검색해서 찾기=> 클릭으로 주소 가져가기의 단계를 거쳐서 원하는 주소를 가져가 db에 저장할 수 있도록 하는 것이 목표이다. 이 코드를 짜는 데에는 복잡함도 복잡함이지만, 어디서 콘솔을 찍어야 내가 알고 싶은 함수나 데이터를 찾아낼 수 있는지 탐색하는 것도 힘들었다. 이번에는 카카오맵API의 자세한 샘플이 있어서 코드를 쉽게 짤 수 있었지만 다른 복잡한 API같은 것들은 어떻게 하면 잘 활용할 수 있을지도 생각해보아야할 것 같다.
/* global kakao */
import { useEffect, useState } from "react";
const KakaoMap = ({ address, setAddress }) => {
const [searchResult, setSearchResult] = useState(
"제주특별자치도 제주시 첨단로 242"
);
const [search, setSearch] = useState("");
useEffect(() => {
// 지도 생성하기
// 지도를 생성할 곳 지정하기
const container = document.getElementById("map");
// 지도 옵션 결정하기 -지도 중심과 축척
const options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 3,
};
// 지도 생성하기
const map = new kakao.maps.Map(container, options);
// 주소-좌표 변환 객체를 생성합니다
let geocoder = new kakao.maps.services.Geocoder();
// 장소 검색 객체를 생성합니다
let ps = new kakao.maps.services.Places();
// 좌표로 주소 검색- 자세하게
const serchDetailAddFromCoords = (coords, callback) => {
geocoder.coord2Address(coords.getLng(), coords.getLat(), callback);
};
// 키워드 검색 완료 시 호출되는 콜백함수 입니다
const placesSearchCB = (data, status) => {
if (status === kakao.maps.services.Status.OK) {
// 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
// LatLngBounds 객체에 좌표를 추가합니다
var bounds = new kakao.maps.LatLngBounds();
for (var i = 0; i < data.length; i++) {
displayMarker(data[i]);
bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
}
// 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
map.setBounds(bounds);
}
};
// 키워드로 장소를 검색합니다
ps.keywordSearch(searchResult, placesSearchCB);
// 검색결과 마커
const displayMarker = (place) => {
let marker = new kakao.maps.Marker({
map: map,
position: new kakao.maps.LatLng(place.y, place.x),
});
kakao.maps.event.addListener(marker, "click", () => {
// 마커를 클릭하면 주소가져가기
setAddress(place.address_name);
});
};
// 지도에 마커찍기
// 지도 중심에 마커 만들기
const marker = new kakao.maps.Marker({
position: map.getCenter(),
});
//마커 찍기
marker.setMap(map);
// 클릭으로 마커 이동하기 + 마커 찍은 곳 정보 가져가기
kakao.maps.event.addListener(map, "click", (mouseEvent) => {
// 지도에서 클릭한 위치의 정보 가져오기
let latIng = mouseEvent.latLng;
// 문자 주소 도출-자세하게
serchDetailAddFromCoords(latIng, (result, status) => {
if (status === kakao.maps.services.Status.OK) {
let detailAddress = result[0].address.address_name;
setAddress(detailAddress);
}
});
// 클릭한 위치로 마커 이동하기
marker.setPosition(latIng);
});
}, [searchResult]);
return (
<>
<form>
<input
onChange={(e) => setSearch(e.target.value)}
placeholder="주소를 입력하세요"
/>
<button
onClick={(e) => {
e.preventDefault();
setSearchResult(search);
}}
>
검색
</button>
</form>
<p>현재 주소 : {address}</p>
<div id="map" className="w-3/4 h-60"></div>
</>
);
};
export default KakaoMap;
'til' 카테고리의 다른 글
아웃소싱 프로젝트 6일 차(완) @무한 스크롤 실패, 프로젝트 회고 (0) | 2024.09.23 |
---|---|
아웃소싱 프로젝트 5일 차 @선별적으로 데이터 불러오기, 무한 스크롤 (0) | 2024.09.20 |
아웃소싱 프로젝트 2일 차 @라우터, 지도API (0) | 2024.09.13 |
아웃소싱 프로젝트 1일 차 @팀 회의 (6) | 2024.09.12 |
리액트 심화 5일 차(完) @프로젝트 다듬기, 개인과제 재제출 (1) | 2024.09.11 |