요즘 캠프에서 아침마다 면접준비를 하는데 오늘 우리 팀의 면접 질문이 "쿼리스트링"에 대한 질문이었다.
팀프로젝트를 하면서 검색기능이나 페이지네이션을 구현했었는데 내가 실제로 사용했던 코드와 정리하면 나중에 답변 정리하기 좋을 것 같아서 작성해보았다.
쿼리스트링
쿼리 스트링(Query String)은 URL 끝에 추가되어 서버로 전달되는 데이터를 표현하는 방식이다. ?
기호 뒤에 키=값
형식의 쌍을 나열하며, 여러 파라미터는 &
기호로 구분한다.
예시
https://example.com/search?query=react&page=2&sort=asc
?query=react&page=2&sort=asc
이 부분이 쿼리스트링이 된다.
검색: 특정 키워드를 서버에 전달하여 검색 결과를 얻는다. 예: ?search=hayoung
필터링: 특정 카테고리나 속성으로 데이터를 필터링할 때 사용한다. 예: ?category=tech&sort=desc
페이지네이션: 페이지 번호나 개수를 전달하여 서버에서 원하는 만큼 데이터를 가져온다. 예: ?page=3&limit=20
정렬: 데이터를 특정 기준으로 정렬하는 데 활용된다. 예: ?sort=price&order=asc
쿼리 스트링은 URL에 포함되므로 특수문자는 URL 인코딩이 필요하다. 롤 과제했을 때도 이 인코딩 때문에 관련해서 정리하기도 했었다. 공백은 %20으로 변환되고, &나 = 등은 %26, %3D처럼 변환된다.
브라우저는 자동으로 인코딩하지만, 서버에서는 이를 디코딩하여 사용해야 한다.
쿼리 스트링은 URL에 노출되므로, 민감한 정보를 포함하지 않는 것이 중요!!
URL의 길이 제한(일반적으로 2000자)을 초과하지 않도록 주의하자.
import { ChevronRight, ChevronLeft } from "lucide-react";
// 1. 타입 지정
type PaginationProps = {
totalPages: number; //총 페이지 수
currentPage: number; // 현재 페이지
pageRange: number; // 표시할 페이지 (현재 페이지 기준 최대 5개 보여지게 구현)
movePage: (page: number) => void; // 페이지 변경 함수
};
export default function Pagination({ totalPages, currentPage, pageRange, movePage }: PaginationProps) {
const renderPageNumbers = () => { // 페이지 번호, 이전/다음 버튼 생성
const pageNumbers = [];
const startPage = Math.max(1, currentPage - Math.floor(pageRange / 2));
const endPage = Math.min(totalPages, startPage + pageRange - 1);
// 이전 버튼 (현재 페이지가 1보다 크면 이전 버튼 나옴)
if (currentPage > 1) {
pageNumbers.push(
<button
key="prev"
onClick={() => movePage(Math.max(1, currentPage - pageRange))}>
<ChevronLeft strokeWidth={1} size={30}/>
</button>
);
}
// 페이지 번호 생성 (첫 페이지부터 끝페이지까지 반복문으로 페이지 번호 생성)
for (let i = startPage; i <= endPage; i++) {
pageNumbers.push(
<span
key={i}
onClick={() => movePage(i)}}> {/* 페이지 번호 클릭 시 해당 페이지 이동 */}
{i}
</span>
);
}
// 다음 버튼
if (currentPage < totalPages) {
pageNumbers.push(
<button
key="next"
onClick={() => movePage(Math.min(totalPages, currentPage + pageRange))}>
<ChevronRight strokeWidth={1} size={30} />
</button>
);
}
return pageNumbers;
};
// 렌더링
return <div>{renderPageNumbers()}</div>;
}
프론트엔드에서는 쿼리스트링을 주로 페이지 상태나 요청 파라미터를 관리할 수 있다.
useSearchParams
훅 또는 URLSearchParams
를 이용하여 쿼리스트링을 관리하고 상태 공유 및 URL 로 페이지 상태를 전달할 수 있다.