본문 바로가기
개발/REACT

React 테이블 커스텀하기 / MUI X DataGrid를 파헤쳐보자

by 개발자 구리 2025. 3. 23.

Import

import { DataGrid } from '@mui/x-data-grid';

 

 

행/열 정의하기

import * as React from "react";
import { DataGrid, GridRowsProp, GridColDef } from "@mui/x-data-grid";

const rows: GridRowsProp = [
  { id: 1, title: "컴플리트 언노운", director: "제임스 맨골드", status: "완료" },
  { id: 2, title: "첫 번째 키스", director: "츠카하라 아유코", status: "완료" },
  { id: 3, title: "미키17", director: "봉준호", status: "완료" },
  { id: 4, title: "바람이 분다", director: "미야자키 하야오", status: "감상 중" },
  { id: 5, title: "나는 내일 어제의 너와 만난다", director: "미키 타카히로", status: "완료" },
  { id: 6, title: "대부", director: "프란시스 포드 코폴라", status: "감상 전" }
];

const columns: GridColDef[] = [
  { field: "id", hide: true },
  { field: "title", headerName: "제목", width: 150 },
  { field: "director", headerName: "감독", width: 150 },
  { field: "status", headerName: "현황", width: 150 }
];

export default function App() {
  return (
    <DataGrid rows={rows} columns={columns}/>
  );
}

 

디폴트 스타일 변경하기

 

1) 특정 셀 선택시 파란 선이 나오는게 싫어요 #MuiDataGrid-cell:focus

 

    <DataGrid rows={rows} columns={columns}
      sx={{
        '& .MuiDataGrid-cell:focus': {
          outline: 'none', // 셀 클릭 시 파란 선 제거
        },
      }}
    />

 

 

2) 헤더의 column 사이사이 separator를 제거하고 싶어요 #MuiDataGrid-columnSeparator

    <DataGrid rows={rows} columns={columns}
      sx={{
        '.MuiDataGrid-columnSeparator': {
          display: 'none',
        },
      }}
    />

 

 

필터링/소팅 관련

1) 필터링/소팅 기능을 위한 메뉴 버튼을 없애고 싶어요 #disableColumnMenu

    <DataGrid rows={rows} columns={columns}
      disableColumnMenu={true} // 컬럼 메뉴 비활성화
    />

 

 

2) 커스텀 소팅 기능을 추가하고 싶어요 #onSortModelChange

import React, { useState } from 'react';
import { DataGrid, GridRowsProp, GridColDef } from '@mui/x-data-grid';

const rows: GridRowsProp = [
  { id: 1, title: "컴플리트 언노운", director: "제임스 맨골드", status: "완료" },
  { id: 2, title: "첫 번째 키스", director: "츠카하라 아유코", status: "완료" },
  { id: 3, title: "미키17", director: "봉준호", status: "완료" },
  { id: 4, title: "바람이 분다", director: "미야자키 하야오", status: "감상 중" },
  { id: 5, title: "나는 내일 어제의 너와 만난다", director: "미키 타카히로", status: "완료" },
  { id: 6, title: "대부", director: "프란시스 포드 코폴라", status: "감상 전" }
];

const columns: GridColDef[] = [
  { field: "id", hide: true },
  { field: "title", headerName: "제목", width: 150 },
  { field: "director", headerName: "감독", width: 150 },
  { field: "status", headerName: "현황", width: 150 }
];

export default function App() {
  const [filteredItems, setFilteredItems] = useState(rows);

  const handleSortModelChange = (sortModel) => {
    if (sortModel.length === 0) return; // 정렬 조건이 없을 경우 무시
  
    const { field, sort } = sortModel[0];
    const sortedItems = [...filteredItems].sort((a, b) => {
      if (a[field] < b[field]) return sort === 'asc' ? -1 : 1;
      if (a[field] > b[field]) return sort === 'asc' ? 1 : -1;
      return 0;
    });

    setFilteredItems(sortedItems); // 정렬된 데이터로 업데이트
  };

  return (
    <DataGrid rows={rows} columns={columns}
      disableColumnMenu={true} // 컬럼 메뉴 비활성화
      onSortModelChange={handleSortModelChange} // 정렬 이벤트 핸들러 추가
    />
  );
}

 

 

 

페이지네이션

1) 디폴트 페이지네이션 UI를 삭제하고 싶어요 #hideFooter

 

    <DataGrid rows={rows} columns={columns}
      hideFooter={true} // 페이지네이션 기능 비활성화
    />

 

 

2) 커스텀 페이지네이션 UI를 추가하고 싶어요

import React, { useState } from 'react';
import { DataGrid, GridRowsProp, GridColDef } from '@mui/x-data-grid';

const rows: GridRowsProp = [
  { id: 1, title: "컴플리트 언노운", director: "제임스 맨골드", status: "완료" },
  { id: 2, title: "첫 번째 키스", director: "츠카하라 아유코", status: "완료" },
  { id: 3, title: "미키17", director: "봉준호", status: "완료" },
  { id: 4, title: "바람이 분다", director: "미야자키 하야오", status: "감상 중" },
  { id: 5, title: "나는 내일 어제의 너와 만난다", director: "미키 타카히로", status: "완료" },
  { id: 6, title: "대부", director: "프란시스 포드 코폴라", status: "감상 전" }
];

const columns: GridColDef[] = [
  { field: "id", hide: true },
  { field: "title", headerName: "제목", width: 150 },
  { field: "director", headerName: "감독", width: 150 },
  { field: "status", headerName: "현황", width: 150 }
];

export default function App() {
  const [currentPage, setCurrentPage] = useState(1);
  const handlePageChange = (pageNumber) => setCurrentPage(pageNumber);

  const itemsPerPage = 5;
  const totalPages = Math.ceil(rows.length / itemsPerPage);

  /* 현재 페이지에 표시할 데이터 */
  const indexOfLastItem = currentPage * itemsPerPage;
  const indexOfFirstItem = indexOfLastItem - itemsPerPage;
  const currentItems = rows.slice(indexOfFirstItem, indexOfLastItem);

  const renderPagination = () => {
    const pageNumbers = [];
    for (let i = 1; i <= totalPages; i++) {
      pageNumbers.push(
        <span
          key={i}
          onClick={() => handlePageChange(i)}
          style={{
            margin: '0 5px',
            cursor: 'pointer',
            fontWeight: i === currentPage ? 'bold' : 'normal',
            color: i === currentPage ? '#007bff' : 'black',
          }}
        >
          {i}
        </span>
      );
    }
    return <div className="d-flex justify-content-center mt-3">{pageNumbers}</div>;
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
      <>
        <DataGrid rows={currentItems} columns={columns}
          hideFooter={true} // 페이지네이션 기능 비활성화
        />
        { renderPagination() }
      </>
    </div>
  );
}

 

 

그 외 커스터마이징

1) 헤더에 스타일을 추가하고 싶어요 #MuiDataGrid-columnHeader

    <DataGrid rows={rows} columns={columns}
      sx={{
        '& .MuiDataGrid-columnHeader': {
          backgroundColor: '#f2f2f2', // 헤더 배경색
          fontWeight: 'bold', // 헤더 텍스트 굵게
        },
      }}
    />

 

 

2) 각 column의 비율을 조정하고 싶어요 #flex

const columns: GridColDef[] = [
  { field: "id", hide: true },
  { field: "title", headerName: "제목", flex: 3 },
  { field: "director", headerName: "감독", flex: 2 },
  { field: "status", headerName: "현황", flex: 2 }
];

 

 

3) 시각화를 위해 cell에 디자인을 추가하고 싶어요 #renderCell

const columns: GridColDef[] = [
  { field: "id", hide: true },
  { field: "title", headerName: "제목", flex: 3 },
  { field: "director", headerName: "감독", flex: 2 },
  {
    field: "status",
    headerName: "현황",
    flex: 2,
    renderCell: (params) => {
      const statusStyles = {
        "완료": { backgroundColor: "#D4EDDA", color: "#155724", dotColor: "#28A745" },
        "감상 중": { backgroundColor: "#FFF3CD", color: "#856404", dotColor: "#FFC107" },
        "감상 전": { backgroundColor: '#F8D7DA', color: '#721C24', dotColor: '#DC3545' },
      };

      const status = params.value;
      const style = statusStyles[status] || {};
      const dotColor = style.dotColor || "#6C757D";

      return (
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            gap: "0.5rem",
            borderRadius: "10px",
            backgroundColor: style.backgroundColor,
            color: style.color,
            padding: "0rem 0.75rem",
            height: "30px",
            marginTop: "0.6rem",
          }}
        >
          <Box
            sx={{
              width: "10px",
              height: "10px",
              borderRadius: "50%",
              backgroundColor: dotColor,
            }}
          />
          {status}
        </Box>
      );
    },
  },
];

 

 

 

 

 

참고

https://mui.com/x/api/data-grid/data-grid/

 

DataGrid API - MUI X

API reference docs for the React DataGrid component. Learn about the props, CSS, and other APIs of this exported module.

mui.com