Material React Table의 페이지네이션 모양이 정말 별로라서..
커스텀 하는 방법을 꽤 오래 찾아야 했어서 써본다

테이블을 사용하는 곳

<MaterialReactTable
	 renderBottomToolbar={({ table }) => {
            return <Pagination table={table} />;
          }}
/>

당연히 data, columns 값 들어가야 한다
여기엔 페이지네이션에 해당하는 부분만 작성함!
table을 넘겨주고, 페이지네이션 용 컴포넌트에 props로 넘긴다
(mrt에서 지원하는게 아닌 내가 만든 컴포넌트가 이름이 Pagination임)

Pagination 컴포넌트

export default function Pagination({ table }: any) {
	const { getPageCount, setPageIndex, getState } = table;
}

일단 props로 받아온 테이블에서 사용할 것들을 할당한다

  • getPageCount : 전체 페이지수
  • setPageIndex : 현재 보게 할 페이지를 설정
  • getState : getState().pagination.pageIndex로 현재 페이지의 index 가져오기

전체페이지 길이, 현재페이지, 현재페이지 세팅 함수 이렇게 세개 가져오는것~


return 하기 전에..

pageArrIdx

기본적으로 페이지를 하나씩 옮기기 때문에, 원하는 모양을 만드려면 5개씩 끊어서 새로운 배열 state를 만들었다
pageArrIdx는 현재 보고있는 arr를 조절하는 state인것

전체 길이를 받아와서, 5개씩 끊어 array를 만든다
ex) 페이지가 총 10개라면 [[1,2,3,4,5] , [6,7,8,9,10]] 이렇게!

const [pageArrIdx, setPageArrIdx] = useState<number>(0);

  // 5페이지 단위로 끊어서 totalpage 길이에 맞춰 배열 생성
  const pageArr = makePageArr(getPageCount());
  function makePageArr(total: number) {
    if (total === 0) return [[]];
    const result = [];
    let start = 1;
    while (start <= total) {
      let end = start + 4;
      if (end > total) end = total;

      const subArray = [];
      for (let i = start; i <= end; i++) {
        subArray.push(i);
      }
      result.push(subArray);
      start += 5;
    }
    return result;
  }

Pagination return 부분

return (
      <div className="w-full flex flex-row my-2 justify-center p-2">
        {pageArrIdx !== 0 && (
          <button
            onClick={() => {
              setPageIndex(0);
              setPageArrIdx(0);
            }}
            className="text-gray-400 border border-gray-300 rounded-lg p-1 mx-1"
          >
            <SkipPreviousIcon />
          </button>
        )}
        {pageArrIdx !== 0 && (
          <button
            onClick={() => {
              setPageArrIdx((prev) => prev - 1);
              setPageIndex(pageArr[pageArrIdx - 1][4] - 1);
            }}
            className="text-gray-400 border border-gray-300 rounded-lg p-1 mx-1"
          >
            <NavigateBeforeIcon />
          </button>
        )}
        {pageArr[pageArrIdx].map((o) => (
          <button
            key={o}
            onClick={() => setPageIndex(o - 1)}
            className={
              "rounded-lg w-[34px] h-[34px] mx-1 border " + (getState().pagination.pageIndex + 1 === o ? "text-pink-400 border-pink-400" : "text-gray-600 border-gray-300")
            }
          >
            {o}
          </button>
        ))}
        {pageArrIdx !== pageArr.length - 1 && (
          <button
            onClick={() => {
              setPageArrIdx((prev) => prev + 1);
              setPageIndex(pageArr[pageArrIdx + 1][0] - 1);
            }}
            className="text-gray-400 border border-gray-300 rounded-lg p-1 mx-1"
          >
            <NavigateNextIcon />
          </button>
        )}
        {pageArrIdx !== pageArr.length - 1 && (
          <button
            onClick={() => {
              setPageIndex(getPageCount() - 1);
              setPageArrIdx(pageArr.length - 1);
            }}
            className="text-gray-400 border border-gray-300 rounded-lg p-1 mx-1"
          >
            <SkipNextIcon />
          </button>
        )}
      </div>
  );

기본 모양은
<< < 1 2 3 4 5 > >>
이런식이고 아이콘은 MUI에서 사용하였다
CSS는 tailwind 이용

<<, >> : 맨 처음, 마지막 페이지로
<, >: 이전,다음 배열로 이동
ex) 현재 [6,7,8,9,10] 이 표현되는 배열일때 < 를 누르면 [1,2,3,4,5]로 이동되고 페이지는 이전에 어디였든 상관없이 5페이지로 간다

이런 로직을 바탕으로 예외처리도 모두 진행하였다!
같은 배열 안에서 페이지 이동은 해당 숫자를 누르면 setPageIndex를 해주면 되는데,

주의할 점은, 페이지 카운트나 pageArr의 숫자는 1부터 시작하는 사용자 기준이지만,
setPageIndex는 기존 방식대로 0부터 사용한다!

(화살표 쓸일이 없으면 전부 안보이게 처리)

'React > MRT' 카테고리의 다른 글

[MRT] 여러 정보를 한컬럼 내에서 사용하기  (0) 2023.10.04

작업하다가 표출은 name으로, 내부적으로 사용은 id를 사용해야하는 상황이 생겼다
(클릭하면 Modal이 열려야하는데, id 정보를 보내야 하기 때문)
이전에 작업했던 내역은 아이콘을 무조건 표출하고 아이디값을 고정으로 받아왔었기 때문에 전혀 도움이 되지 않았다ㅠㅠ

 

<이전 작업 예시>

        accessorKey: "id",
        header: "예시"
        Cell: ({ renderedCellValue }: any) => {
          if (renderedCellValue)
            return (
              <span
                className="cursor-pointer"
                onClick={() => {
                  setReportId(renderedCellValue);
                  setReportToggle(true);
                }}
              >
                {<DescriptionIcon />}
              </span>
            );
          else return
          <span className="text-gray-300">{<DescriptionIcon />}</span>;
        },

 

그래서 열심히 찾다가 row에 정보가 담겨있어서 한번에 정보를 사용할수 있다는걸 찾았다!

 

<해결>

       accessorFn: (row) => row.name,
        header: "이름",
        Cell: ({ row }) => <span>{row.original.name}</span>,
        muiTableBodyCellProps: ({ row }) => ({
          onClick: (event) => {
            setIdForModal(row.original.id);
            setIsToggle(true);
          },
          style: {
            cursor: "pointer",
          },
        }),

 

row.original로 해당 row의 데이터 전체에 접근 가능

muiTableBodyCellProps를 사용해야 cell 아무곳이나 클릭했을때 전부 클릭 이벤트를 넣을 수 있다.

'React > MRT' 카테고리의 다른 글

[MRT] 테이블 페이지네이션 커스텀  (0) 2023.10.04