[React] 페이지네이션 구현

jsha·2023년 6월 27일
0

이전 프로젝트에서는 라이브러리를 사용해서 페이지네이션을 구현했었는데,
이번에는 라이브러리 없이 구현에 성공하였다. 로직을 짜는게 생각보다 복잡해서, 시간이 좀 걸렸지만😅 기억에 오래 남기기 위해 쭉 정리해보았다.


const renderButtons = (num: number, page: number) => {
    // num === 전체 페이지 수

    // pages === start=1~total로 이동하는 모든 버튼이 담겨져 있는 array
    const pages = [];
    for (let i = 1; i <= num; i++) {
      pages.push(
        <span
          key={i}
          className='pagination-button'
          onClick={() => {
            window.location.href = `/search?searchKeyword=${queryObject.searchKeyword}&queryType=${queryObject.queryType}&searchTarget=${queryObject.searchTarget}&start=${i}`;
          }}
        >
          {i}
        </span>
      );
    }

    const offset = page * 5; // 5개 자를거야.
    let result: any[] = []; // 결과 담을 array

    if (pages.length > 0) {
      result = pages.slice(offset, offset + 5);
      // pages를 자르는데 offset이 0이면 0~4가 남겠지?
      // 0~4가 보이는 한 페이지가 나올거야.
    }
    return result;
  };
<div className='flex flex-wrap justify-center w-full max-w-screen-xl mb-10'>
        {queryObject.start !== '1' ? (
         // 시작 버튼 값이 1이 아닌 경우 이전 페이지로 이동하는 버튼을 만들거야.
          <span
            className='pagination-button'
            onClick={() => {
              window.location.href = `/search?searchKeyword=${
                queryObject.searchKeyword
              }&queryType=${queryObject.queryType}&searchTarget=${queryObject.searchTarget}&start=${
                Number(queryObject.start) - 1
              }`;
            }}
          >
            {`<`}
          </span>
        ) : null}
        {Math.floor((Number(queryObject.start) - 1) / 5) 
          // 결과값이 0 이 아닌 경우 1 버튼으로 이동하는 버튼과 생략부호(...)가 생성될거야.
          === 0 ? null : (
          <>
            <span
              className='pagination-button'
              onClick={() => {
                window.location.href = `/search?searchKeyword=${
                  queryObject.searchKeyword
                }&queryType=${queryObject.queryType}&searchTarget=${
                  queryObject.searchTarget
                }&start=${1}`;
              }}
            >
              {`1`}
            </span>
            <span className='text-gray-500 flex-center'>···</span>
          </>
        )}
        {renderButtons(totalPage, Math.floor((Number(queryObject.start) - 1) / 5))}
// 위의 renderButtons 함수를 이용하여 새로운 페이지의 버튼들을 렌더링해.

        {Math.ceil(Number(queryObject.start) / 5) === Math.ceil(totalPage / 5) ? null : (
          // 생략부호와 마지막 버튼으로 이동하는 버튼이 생성돼.
          <>
            <span className='text-gray-500 flex-center'>···</span>
            <span
              className='pagination-button'
              onClick={() => {
                window.location.href = `/search?searchKeyword=${queryObject.searchKeyword}&queryType=${queryObject.queryType}&searchTarget=${queryObject.searchTarget}&start=${totalPage}`;
              }}
            >
              {`${totalPage}`}
            </span>
          </>
        )}

        {Number(queryObject.start) !== totalPage ? (
// 다음 페이지로 이동하는 버튼이 생성돼.
          <span
            className='pagination-button'
            onClick={() => {
              window.location.href = `/search?searchKeyword=${
                queryObject.searchKeyword
              }&queryType=${queryObject.queryType}&searchTarget=${queryObject.searchTarget}&start=${
                Number(queryObject.start) + 1
              }`;
            }}
          >
            {`>`}
          </span>
        ) : null}
      </div>

⭐️ 완성 ⭐️

예를들어, 총 토탈버튼이 48개야. 이걸 5로 나눈다면 총 10페이지가 나와야겠지?
1 ~ 5 (1페이지)/ 5 ~ 10 (2페이지)/ 11 ~ 15 (3페이지) / ... / 41 ~ 45 (9페이지)/ 46 ~ 48 (10페이지)
➡️ 총 10개

그런데 1페이지에서는 처음으로 돌아가는 버튼이 보이면 안되고.
6버튼부터는(2페이지) 처음으로 돌아가는 버튼과 마지막 페이지로 가는 버튼이 보여야 됨. 그리고 마지막 10페이지인 46번 버튼부터는 처음으로 돌아가는 버튼만 보이면 됨.

0개의 댓글

관련 채용 정보