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 |
---|