MUI(Material UI)のDataGridでセルとヘッダーに独自のコンポーネントを設置する方法【React】

ReactのUIフレームワークであるMUI(Material UI)のDataGridにて、セルとヘッダーに独自のコンポーネントを設置する方法を解説していきます。
セルの中にクリックできるボタンを設置したりと色々とカスタマイズすることができます。

## MUI DataGridのセルの中にコンポーネントを設置する

```tsx
import { Button, Container } from '@mui/material'
import { DataGrid, GridColDef, GridRenderCellParams } from '@mui/x-data-grid'

const Home = () => {
  const columns: GridColDef[] = [
    { field: 'id', headerName: 'ID' },
    { field: 'name', headerName: 'NAME' },
    {
      field: 'email',
      headerName: 'E-MAIL',
      width: 200,
      renderCell: (params) => {
        return <RenderCellComponent {...params} />
      }
    }
  ]

  const RenderCellComponent = (params: GridRenderCellParams) => {
    const onClick = () => {
      alert(params.row.email)
    }
    return (
      <Button variant="contained" onClick={onClick} fullWidth>
        Click
      </Button>
    )
  }

  const rows = [
    {
      id: 1,
      name: 'Taro',
      email: 'test1@gmail.com'
    },
    {
      id: 2,
      name: 'Ken',
      email: 'test2@gmail.com'
    },
    {
      id: 3,
      name: 'Yui',
      email: 'test3@gmail.com'
    }
  ]

  return (
    <Container>
      <DataGrid columns={columns} rows={rows} autoHeight checkboxSelection />
    </Container>
  )
}

export default Home
```

`columns`の`renderCell`にコンポーネントを返すことで独自のコンポーネントをセル内に配置することができます。
`renderCell`のコールバック関数でセルの情報を受け取りコンポーネントに渡すことができます。

```tsx
renderCell: (params) => {
  return <RenderCellComponent {...params} />
}
```
今回の例ではMUIのButton Componentを配置しています。
![mui-rendercell2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/af91c646-f8aa-9eb4-2716-76740e7685e3.png)

`onClick`などのイベントも設定することが可能です。

![mui-rendercell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/dc909073-96a9-5092-3298-b3d8e7404503.png)

## MUI DataGridのヘッダーの中にコンポーネントを設置する

```tsx
import EmailIcon from '@mui/icons-material/Email'
import { Box, Container } from '@mui/material'
import { DataGrid, GridColDef, GridColumnHeaderParams } from '@mui/x-data-grid'

const Home = () => {
  const columns: GridColDef[] = [
    { field: 'id', headerName: 'ID' },
    { field: 'name', headerName: 'NAME' },
    {
      field: 'email',
      headerName: 'E-MAIL',
      width: 200,
      renderHeader: (params: GridColumnHeaderParams) => {
        return <RenderHeaderComponent {...params} />
      }
    }
  ]

  const RenderHeaderComponent = (params: GridColumnHeaderParams) => {
    return (
      <Box display="flex" sx={{ alignItems: 'center' }}>
        <EmailIcon color="inherit" />
        <Box>{params.colDef.headerName}</Box>
      </Box>
    )
  }

  const rows = [
    {
      id: 1,
      name: 'Taro',
      email: 'test1@gmail.com'
    },
    {
      id: 2,
      name: 'Ken',
      email: 'test2@gmail.com'
    },
    {
      id: 3,
      name: 'Yui',
      email: 'test3@gmail.com'
    }
  ]

  return (
    <Container>
      <DataGrid columns={columns} rows={rows} autoHeight checkboxSelection />
    </Container>
  )
}

export default Home
```
![mui-renderheader.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/4a698dfb-dc78-f0ad-eac4-0594bd429f6c.png)

`columns`の`renderHeader`にコンポーネントを返すことで、独自のコンポーネントをDataGridのヘッダー内に配置することができます。アイコンなどを一緒に表示する際などに役立つかなと思います。

`renderHeader`のコールバック関数でヘッダーの情報を受け取りコンポーネントに渡すことができます。

```tsx
renderHeader: (params: GridColumnHeaderParams) => {
  return <RenderHeaderComponent {...params} />
}

const RenderHeaderComponent = (params: GridColumnHeaderParams) => {
  console.log(params.colDef.headerName)
}
```

## 参考
https://mui.com/x/react-data-grid/