일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- SSL
- nextJS
- 인증서
- aws
- nginx
- 브라우저
- 로드 밸런싱
- 렌더링 과정
- SSH
- TLS
- tcp
- 자동화
- 3-Way HandShake
- workflow
- gitgub actions
- 이미지 압축
- DNS
- https
- ec2
- 리버스 프록시
- CI
- 이미지 포맷 변경
- 배포
- pm2
- 이미지 최적화
- 무중단
- webp
- 성능 개선
- certbot
- 검색엔진최적화
- Today
- Total
개발일기
카카오 지도 api에서 pagination을 통한 45개 데이터 가져오기 본문
개요
카카오 지도 api를 사용하면서 분명 45개의 데이터를 제공한다고 되어있는데 왜 15개만 제공되는 의문이였다. 나머지 데이터를 얻기 위해 많이 헤맨 결과 pagination을 통해 45개의 데이터를 얻을 수 있다라는 걸 발견했다. 그래서 프로젝트를 진행하면서 45개의 데이터를 활용하기 위해 pagination을 구현한 것과 다른 기능을 만들면서 경험한 한계(?)에 대해 적어보려고 한다. 페이지네이션을 구현 해보자.
pagination
검색 결과의 페이징을 담당하는 클래스.
하나의 검색 결과에 대해 페이지 이동을 쉽게 할 수 있도록 도와준다.
직접 선언은 불가능하며 검색 결과를 다루는 콜백함수의 인자로 인스턴스가 생성되어 넘어온다.
공식문서에 나와있는 내용이다.
var places = new kakao.maps.services.Places();
// callback의 세 번째 인자로 Pagination의 인스턴스가 넘어온다.
var callback = function(result, status, pagination) {
if (status === kakao.maps.services.Status.OK) {
// do something
// 특정 엘리먼트를 클릭했을 경우 다음 페이지 검색을 시도하는 예제
var nextBtn = document.getElementById('nextBtn');
nextBtn.click(function() {
// 속성 값으로 다음 페이지가 있는지 확인하고
if (pagination.hasNextPage) {
// 있으면 다음 페이지를 검색한다.
pagination.nextPage();
}
});
}
};
places.keywordSearch('판교 치킨', callback);
Methods
nextPage() - 다음 페이지를 검색한다.
prevPage() - 이 전 페이지를 검색한다.
gotoPage(page) - 저장한 페이지를 검색한다.
gotoFirst() - 가장 처음 페이지를 검색한다.
gotoLast() - 가장 마지막 페이지를 검색한다.
totalCount - 현재 검색의 결과 목록의 총 갯수
hasNextPage - 현재 검색 결과 기준, 다음 페이지가 있는지 여부
hasPrevPage - 현재 검색 결과 기준, 이 전 페이지가 있는지 여부
current - 현재 페이지 번호
적용하기
import {
boundsState,
markersState,
myLocationState,
selectShopsState,
} from "@/globalState/recoilState";
import { MarkersType, PaginationType } from "@/types/placeType";
import React, { useState } from "react";
import { useRecoilState, useRecoilValue } from "recoil";
const useKakaoSearch = () => {
const myLocation = useRecoilValue(myLocationState);
const [selectshops, setSelectshops] = useRecoilState(selectShopsState);
const [pagination, setPagination] = useState<PaginationType>();
const [, setBounds] = useRecoilState<any>(boundsState);
const [, setMarkers] = useRecoilState<MarkersType[]>(markersState);
const searchPlaces = (currentPage: number = 1) => {
const ps = new window.kakao.maps.services.Places();
const keyword = "의류판매";
const options: kakao.maps.services.PlacesSearchOptions = {
location: new window.kakao.maps.LatLng(
myLocation.center.lat,
myLocation.center.lng
),
sort: window.kakao.maps.services.SortBy.ACCURACY,
page: currentPage,
};
ps.keywordSearch(
keyword,
(data, status, pagination) => placesSearchCB(data, status, pagination),
options
);
};
// 장소의 정보를 얻을 수 있고, 그 정보를 state에 담아서 활용,
// pagination을 따로 만들기 위해 pagination 또한 state에 담아서 활용
const placesSearchCB = (
data: any[],
status: string,
pagination: PaginationType
) => {
if (status === window.kakao.maps.services.Status.OK) {
setSelectshops(data);
displayPlaces(data);
setPagination(pagination);
}
};
// 장소의 좌표를 표기하기 위한 함수
const displayPlaces = (data: any[]) => {
const bounds = new window.kakao.maps.LatLngBounds();
let newMarkers: MarkersType[] = [];
data.forEach((place) => {
const position = { lat: place.y, lng: place.x };
newMarkers.push({ position });
bounds.extend(new window.kakao.maps.LatLng(position.lat, position.lng));
});
setMarkers(newMarkers);
setBounds(bounds);
};
return { searchPlaces, pagination, selectshops, myLocation };
};
export default useKakaoSearch;
인자로 pagition만 받으면 45개의 데이터를 활용할 수 있는건 아니다. 공식 문서와 같이 pagination의 메서드를 사용해서 다음 데이터를 얻어야 한다. 이유는 카카오 지도 api에서 45개의 데이터를 한번에 제공하지 않고 15개, 15개, 15개씩 나눠서 제공한다. 그렇기 때문에 다음 15개의 데이터를 보기 위해서 pagination을 구현 해야 한다.
pagination 구현하기
import React, { RefObject, useEffect } from "react";
import styled from "styled-components";
import Chevron from "@/assets/Chevron.svg";
import Chevrons from "@/assets/Chevrons.svg";
import { styleColor } from "@/styles/styleColor";
interface PropsType {
pagination: any;
currentPage: number; // 1이 기본값
setCurrentPage: (page: number) => void;
scrollRef : RefObject<HTMLDivElement>
}
const PaginationContainer = ({
pagination,
currentPage,
setCurrentPage,
scrollRef
}: PropsType) => {
// 페이지 이동시 가장 위로 이동
useEffect(()=>{
if (scrollRef.current) {
scrollRef.current.scrollTo({ top: 0 });
}
},[pagination])
const nextPageButtonHandler = () => {
if (pagination && pagination.hasNextPage) {
setCurrentPage(currentPage + 1);
pagination.nextpage;
}
};
const prevPageButtonHandler = () => {
if (pagination && pagination.hasPrevPage) {
setCurrentPage(currentPage - 1);
pagination.prevPage;
}
};
return (
<S.PaginationContainer>
<S.PageButtonWrap>
<button onClick={() => setCurrentPage(pagination.first)}>
<Chevrons
transform={"rotate(180)"}
fill={`${styleColor.GRAY[400]}`}
/>
</button>
<button onClick={prevPageButtonHandler}>
<Chevron transform={"rotate(180)"} fill={`${styleColor.GRAY[400]}`} />
</button>
</S.PageButtonWrap>
<S.PageNumberButtons>
{Array.from({ length: pagination?.last }).map((_, index) => {
return (
<S.PageNumberButton
key={index}
$index={index + 1}
$currentPage={currentPage}
onClick={() => setCurrentPage(index + 1)}
>
{index + 1}
</S.PageNumberButton>
);
})}
</S.PageNumberButtons>
<S.PageButtonWrap>
<button onClick={nextPageButtonHandler}>
<Chevron fill={`${styleColor.GRAY[400]}`} />
</button>
<button onClick={() => setCurrentPage(pagination.last)}>
<Chevrons fill={`${styleColor.GRAY[400]}`} />
</button>
</S.PageButtonWrap>
</S.PaginationContainer>
);
};
export default PaginationContainer;
const S = {
//...css code
};
결과
마무리
다른 기능을 하면서 카카오지도 api에서 제공하는 것을 그대로 사용해서 구현하기에는 조금 이질감이 있어서 데이터를 받아오는 방법과 pagination을 구현한 방법을 조금씩 변경해서 사용을 했는데 그것은 다음 글에서 설명하도록 하겠다. 위와 같이 데이터 45개를 pagination을 통해 받아 보았고 역시 공식문서를 보는 건 너무 어려운 일이였다.
'SideProject(My-Selectshop-Finder)' 카테고리의 다른 글
NextAuth 사용자 정보 update 및 mutate 하기 (0) | 2025.02.03 |
---|---|
카카오 지도 API에서 pagination과 필터링: 데이터 정렬 문제 해결하기 (0) | 2024.12.24 |
supabase "Could not find the ' ' column of ' ' in the schema cache" 에러 해결 (0) | 2024.12.02 |
카카오 지도 API 현재 위치 좌표로 주소 얻어내기(NextJs) (0) | 2024.08.18 |
비밀번호 표시에 웹 접근성 및 사용자를 위한 tabIndex 활용 (0) | 2024.08.04 |