공삼
article thumbnail


 문제 상황

react 프로젝트 진행중 게시판의 게시글이 많아질수록 스크롤이 많아지고 가독성이 떨어지는 문제점을 해결하기 위해 pagination을 사용하기로 했다. 

 

 

 

 

💡 문제 해결

현재 우리 프로젝트의 코드는 게시글들을 firebase에서 받아온 데이터들을 props로 받아 map을 이용해 넘겨주는 함수와 그것들을 인자로 받아 랜더링 시켜주는 함수가 있다. 

 

여기서 처음 contents를 props로 받고, map을 이용해 다른 함수로 넘겨주기 전에 pagination을 이용해야 한다. 

 

 

이해를 돕기위해 코드를 추가하면

function BoardItem({ title, content, id, like }) {
  return (
    <div className="text-left  flex py-2 lg:py-3 border border-transparent border-b-gray-300 w-full">
      <span className="text-gray-500 text-center max-sm:w-[15vw] truncate w-[25vw] font-medium">{title}</span>
      <Link className="w-full px-3 overflow-hidden" to={`${id}`}>
        {content}
      </Link>
      <span className="max-sm:w-[clamp(50px,10vw,60px)] w-[clamp(60px,7vw,70px)] flex justify-between">
        <BsHandThumbsUpFill className="mt-[1px]" />
        {like}
      </span>
    </div>
  );
}

해당 코드로 넘겨주기 전에 pagination을 이용하여 데이터를 처리하고 필요한 부분만 BoardItem 함수로 넘겨준다는 말이다.

 

그리고 우리가 사용한 pagination을 사용하기 위해선 아래에 참고문헌으로 가 react-paginate 먼저 설치해야한다. 

 

const BoardListItem = ({ contents }) => {
  // 한 페이지당 보여줄 갯수
  const perPage = 10;
  // 현재 페이지
  const [currentPage, setCurrentPage] = useState(0);

  // selectedPage 현재 페이지의 번호
  // 버튼을 누를때마다 호출됨
  const handlePageClick = ({ selected: selectedPage }) => {
    setCurrentPage(selectedPage);
  };

  // 현재 페이지의 시작 인덱스를 계산
  const offset = currentPage * perPage;
  // contents에 들어온 리스트를 slice로 잘라서 자르고 싶은 index 갯수 만큼 자르고 pagedContents에 저장함
  // ex) 0번째 인덱스이면 0 * 10 이기 때문에 0번째 인덱스부터 0 + 10 그러니까 0~10까지 자른 배열을 map으로 돌려줌
  // ex) 1번째 인덱스이면 1 * 10 이므로 10번째부터 10+10 까지 10~20까지 자른 배열을 map으로 돌림
  const pagedContents = contents.slice(offset, offset + perPage);
  //  pageCount={Math.ceil(contents.length / perPage)}
  // Math.ceil은 소수값이 존재할때 값을 올려준다.
  // contents에 들어와있는 11개의 게시물을 perPage 한페이지당 보여줄 갯수인 10 개로 나누어 몇 개의 페이지가 필요한지 구한 것
  return (
    <>
      <div>
        {pagedContents.map((item, index) => (
          <BoardItem key={index} title={item.writer} content={item.title} id={item.id} contents={contents} like={item.like} />
        ))}
      </div>
      <ReactPaginate previousLabel={"<"} nextLabel={">"} pageCount={Math.ceil(contents.length / perPage)} onPageChange={handlePageClick} containerClassName={"pagination"} activeClassName={"active"} />
    </>
  );
};

 

위 코드를 보고 설명해주면 contents는 상위 컴포넌트에서 받은 props로 이제 해당 데이터를 이용하여 처리하고 랜더링 해줘야한다. 

 

perPage는 한 페이지당 보여줄 게시글의 갯수로 계산될 때 사용 된다. 

 

selectedPage는 현재 페이지 번호를 나타내며 버튼을 누르면 현재 페이지인 setCurrentPage에 selectPage를 할당시켜 해당 페이지가 호출되게 된다. 

 

offset은 현재 페이지의 시작 인덱스를 계산하여 주석으로 적어놓은 것과 같이 0~9 까지, 10~19으로 자른 값을 사용하기 위한 객체이다. 

 

중요한 부분은 

pageCount={Math.ceil(contents.length / perPage)}

로 Math의 ceil을 이해하면 쉽다. 

 

📍 Math 는 JavaScript에서 제공하는 내장 객체이며, ceil은 Math 내의 존재하는 메소드 중 하나이다. 

 

ceil은 매개변수로 받은 숫자를 올림한 값을 반환한다. 따라서 contents의 갯수를 perPage 즉, 아까 설정한 10개 로 나누어 올림한 값을 반환하게 된다. 

 

 

 

 

🔗 참고문헌

react-paginate

 

https://www.npmjs.com/package/react-paginate

 

react-paginate

A ReactJS component that creates a pagination.. Latest version: 8.1.4, last published: 5 months ago. Start using react-paginate in your project by running `npm i react-paginate`. There are 493 other projects in the npm registry using react-paginate.

www.npmjs.com

 

profile

공삼

@g_three

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!