페이징
페이징은 어떤 리스트에서도 가장 기본에 속하는 구조다. 여러 개시글의 리스트가 일정 갯수 이상 존재한다면 그 게시글들을 모두 보여주는 방법을 정해야 하는데, 가장 보편적으로 많은 시스템에서 채택한 구조가 페이징이다.
요즘은 페이징기능이 아니라, 내리면 다음 요소들을 불러오는 시스템도 있지만 UX적으로 불편하다고 생각했던게 많아 페이징 구조를 선택했다.
게시글로 작성하지는 않았지만, 현재 API를 통해 게시글을 불러와 리스트를 그리는 부분까지만 구현된 상태다.
useEffect(() => {
const fetchData = async () => {
try {
const sourceParam = selectedSource === '통합' ? '' : `&site=${selectedSource}`; // "통합"이면 필터링 안함
const response = await fetch(`http://localhost:3000/board/all?limit=${itemsPerPage}&page=${currentPage}${sourceParam}`);
if (!response.ok) throw new Error("서버 응답 오류");
const data: Product[] = await response.json();
console.log("받아온 데이터:", data);
setItemsAPI(data);
} catch (error) {
console.error("데이터를 받아오는데 실패했습니다.", error);
}
};
fetchData();
}, [currentPage, selectedSource]);
일전 크롤링으로 저장된 데이터를 불러들여오는 API를 호출하는 프론트단 코드이다. 매개변수로 페이지 번호와, 사이트종류를 넘겨서 해당하는 글의 데이터들만 불러온다. 통신하는 횟수 자체는 많아지지만 속도도 빨라질거라 예상한다.
useEffect
useEffect 훅은 컴포넌트가 렌더링 될 때 작업을 실행하는 기능이다. 1. 컴포넌트가 처음 렌더링 될때 (마운트) 2. 상태/props이 변경될 때 3. 컴포넌트가 사라질때 (언마운트)시 동작한다.
useEffect(() => {
const fetchData = async () => {
try {
setItemsAPI(data);
} catch (error) {
console.error("데이터를 받아오는데 실패했습니다.", error);
}
};
fetchData();
}, [currentPage, selectedSource]);
이 부분만 보면 [currentPage, selectSource] 가 변경될때마다 실행된다. 이 외에도 처음 그려질때 실행된다는 것. SPA의 특성상 페이지의 새로고침이 자주 일어나지 않기때문에 컴포넌트 별로 리렌더링 시키는 행동이 많은데 이 useEffect도 동일하다.
{/* 카테고리 리스트 */}
<div className="flex justify-center items-center space-x-12 h-12">
{["통합", "Arca", "PPomppu", "Quasar"].map(source => (
<button
key={source}
onClick={() => {
console.log(`선택된 소스: ${source}`);
setSelectedSource(source);
setCurrentPage(1);
}}
className={`inline-flex w-32 px-4 py-2 border-b-2 font-semibold transition ${selectedSource === source ? 'text-blue-600 border-blue-500' : 'text-gray-600 hover:text-gray-900 border-transparent hover:border-blue-500'}`}
>
{source}
</button>
))}
</div>
상단부 카테고리 리스트를 변경할 경우 setSelectedSource(), setCurrentPage() 를 이용해 사용중인 useState를 변경시킨다. 그러면 위의 useEffect()를 이용해 리스트 api가 리렌더링되면서 api를 호출한다.
{Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => (
<button
key={page}
onClick={() => handlePageChange(page)}
className={`!px-3 !py-1 rounded-md ${page === currentPage ? 'bg-blue-500 text-white' : ' text-gray-700'}`}
>
{page}
</button>
))}
페이징, 숫자를 클릭했을때 handlePageChange(page)를 이용해 useEffect를 동작시킨다.
또한 페이징을 위한 최대크기 구하는 api도 별도로 만들어 사용한다.
// 페이지 변경 함수
const handlePageChange = (page: number) => {
if (page >= 1) {
console.log(`페이지 변경: ${page}`);
setCurrentPage(page);
}
};
const totalPages = Math.ceil(totalItems / itemsPerPage); // 전체 페이지 수 계산
전체 페이지의 수를 구해야 전체 페이징 섹션을 그리기 때문에 필요하다. 페이지 변경 함수는 번호를 눌렀을때 currentPage 값을 변경시키기 위한 메서드를 실행한다.
'사이드 프로젝트' 카테고리의 다른 글
perplexity 퍼플렉시티 api 사용법, postman 호출해보기 (2) | 2025.03.18 |
---|---|
Nest.js + React.js (Next.js) 사이드 프로젝트 : Repository extend (0) | 2025.03.17 |
nest.js 를 이용해 크롤링 해보기 (1) - puppeteer 동적 크롤링 (0) | 2025.03.07 |
Nest.js + React.js(Next.js) 사이드 프로젝트 : TypeORM save(), insert(), update() (0) | 2025.03.07 |
Nest.js + React.js(Next.js) 사이드 프로젝트 : 트러블슈팅 (0) | 2025.02.28 |