[React] 카카오 맵 API 검색결과 제한 문제 트러블슈팅💫
발생한 문제 🤦♀️
프로젝트를 진행하면서 카카오 맵 API를 이용해 장소 검색 결과를 불러오는 과정에서 문제를 겪었습니다.
사용자가 키워드를 입력하면 그에 해당하는 장소들의 목록을 불러올 때, 검색 결과가 15개로 제한되어 나타나는 문제가 있었습니다.
문제 원인 🤷♀️
이 문제의 원인을 찾기 위해 카카오 맵 API의 문서를 참고하였습니다.
그 결과, 카카오 맵 API는 한 페이지 당 총 15개의 데이터를 제공한다는 사실을 알게 되었습니다.
또한, 페이징을 한다 해도 총 45개 이상의 데이터는 제공하지 않는다고 명시되어 있었습니다.
해결 방안 💁♀️
페이지 버튼을 추가하여 사용자가 버튼을 클릭할 때마다 해당 페이지의 검색 결과가 리스트로 나타나도록 구현하였습니다.
상태 관리
우선, HomePage.jsx에서 mapPagination이라는 state를 추가하고 초기값을 null로 설정해 주었습니다. 그리고 이 state를 SideBar와 MapLoader에 props로 전달하였습니다.
// src > pages > HomePage.jsx
const HomePage = () => {
const [markers, setMarkers] = useState([]);
const [mapPagination, setMapPagination] = useState(null);
return (
<div>
<StContainer>
<SideBar
markers={markers}
setMarkers={setMarkers}
mapPagination={mapPagination}
/>
<MapLoader
markers={markers}
setMarkers={setMarkers}
setMapPagination={setMapPagination}
/>
</StContainer>
</div>
);
};
export default HomePage;
페이징 정보 전달
다음으로, MapLoader.jsx의 Location 컴포넌트에서 페이징 정보를 설정할 때 setMapPagination을 이용해 전달하도록 수정하였습니다.
// src > components > MapLoader.jsx
const Location = ({ markers, setMarkers, setMapPagination }) => {
useEffect(() => {
if (!map) return;
// 장소 검색 객체를 생성
const ps = new kakao.maps.services.Places();
ps.keywordSearch("방탈출", (data, status, pagination) => {
if (status === kakao.maps.services.Status.OK) {
const bounds = new kakao.maps.LatLngBounds();
let markers = [];
for (var i = 0; i < data.length; i++) {
const id = data[i].id;
const placeName = data[i].place_name;
const categoryName = data[i].category_name;
const phoneNumber = data[i].phone;
const jibunAddress = data[i].address_name;
const roadAddress = data[i].road_address_name;
const placeUrl = data[i].place_url;
// setMapPagination을 이용하여 페이징 정보 전달
setMapPagination(pagination);
...
}, [map]);
};
페이지 버튼 및 이동 구현
마지막으로, SideBar.jsx에서는 페이지 버튼을 추가하고, 클릭 시 해당 페이지로 이동하도록 하는 기능을 구현하였습니다.
페이지가 변경될 때마다 mapPagination.getPage()를 통해 현재 페이지를 업데이트하고, 클릭 시 해당 페이지로 이동하도록 설정하였습니다.
// src > components > SideBar.jsx
const SideBar = ({ markers, setMarkers, mapPagination }) => {
const [searchTerm, setSearchTerm] = useState("");
const [currentPage, setCurrentPage] = useState(1);
const buttonsNumber = [1, 2, 3];
// 페이지 번호 클릭 핸들러
const handlePageChange = (pageNumber) => {
mapPagination.gotoPage(pageNumber);
setCurrentPage(pageNumber);
};
return (
<StButtonBox>
{buttonsNumber.map((buttonNumber) => (
<StPageButton
index={buttonNumber}
onClick={() => handlePageChange(buttonNumber)}
$currentPage={currentPage}
>
{buttonNumber}
</StPageButton>
))}
</StButtonBox>
);
};
export default SideBar;
댓글남기기