IT二刀流にはプロモーションが含まれています。

Material-UIの「Data Grid」でデータを更新するコード

reactアイキャッチ

Material-UIの「Data Grid」でデータを更新するサンプルコードです。

セルを一つずつ更新できます。

検証バージョン

  • react: 17.0.2
  • @material-ui/core: 5.0.0-beta.0
  • @material-ui/data-grid: 4.0.0-alpha.35

初期のData Gridコード

表を表示するだけのシンプルなコードです、これに更新機能を実装します。

import * as React from 'react';
import { DataGrid } from '@material-ui/data-grid';

const columns = [
  { field: 'name', headerName: 'Name', width: 180 },
  { field: 'age', headerName: 'Age', type: 'number', width: 140 },
  { field: 'birthday', headerName: 'Birthday', type: 'date', width: 180 },
  { field: 'isAdmin', headerName: 'Is admin?', type: 'boolean', width: 180 },
];

const rows = [
  { id: 1, name: '1st', age:10 , birthday: '2020-01-01', isAdmin: false },
  { id: 2, name: '2nd', age:20 , birthday: '2020-02-02', isAdmin: true },
  { id: 3, name: '3rd', age:30 , birthday: '2020-03-03', isAdmin: false },
];

const DataGridTest = () => {
  return (
    <div style={{ width: '700px' }}>
      <DataGrid
        columns={columns}
        rows={rows}
        autoHeight
      />
    </div>
  );
}
export default DataGridTest;
Data Grid初期
Data Grid初期

更新機能の実装

import * as React from 'react';
import { DataGrid } from '@material-ui/data-grid';
import { Box } from '@material-ui/core';
import { Button } from '@material-ui/core';
import moment from 'moment';
import _ from 'lodash';

const dateFormat = (v) => {
  return moment(v.value).format('YYYY-MM-DD');
};

const columns = [
  { field: 'name', headerName: 'Name', width: 180, editable: true },
  { field: 'age', headerName: 'Age', type: 'number', width: 140, editable: true },
  { field: 'birthday', headerName: 'Birthday', type: 'date', width: 180, editable: true, valueFormatter: dateFormat },
  { field: 'isAdmin', headerName: 'Is admin?', type: 'boolean', width: 180, editable: true },
];

const data = [
  { id: 1, name: '1st', age:10 , birthday: '2020-01-01', isAdmin: false },
  { id: 2, name: '2nd', age:20 , birthday: '2020-02-02', isAdmin: true },
  { id: 3, name: '3rd', age:30 , birthday: '2020-03-03', isAdmin: false },
];

const DataGridTest = () => {
  const [rows, setRows] = React.useState(data);

  // データの確認
  const checkRows = () => console.log(rows);

  // セルの更新
  const changeCell = (v) => {
    let newValue = _.cloneDeep(rows); /* lodashでstateをディープコピー */
    let idx = rows.findIndex(d => d.id == v.id);  /* 該当データのindexを取得 */
    newValue[idx][v.field] = v.value;
    setRows(newValue)  /* 編集されたデータを置き換える */
  }

  return (
    <div style={{ width: '800px' }}>
      <Box component='div' sx={{ p: 2, textAlign: 'right' }}>
        <Button variant="contained" color='primary' onClick={checkRows}>確認</Button>
      </Box>
      <DataGrid
        columns={columns}
        rows={rows}
        autoHeight
        onCellEditCommit={changeCell}
      />
    </div>
  );
}
export default DataGridTest;

columnsの編集可能にしたい項目に「editable: true」を設定します。

「onCellEditCommit」でデータ更新完了時に「changeCell()」イベントを実行します。

まずはstateのrowsをnewValueにコピーします。

lodashを使ってディープコピーをおこなっています、Reactのstateはそのまま変更してはダメなようなので。

その後に該当のデータを上書きしてsetRowsでrowsに設定します。

確認ボタンを押せば現在のrowsの値が確認できます。

DataGrid更新1
変更前
DataGrid更新2
変更後
DataGrid更新3
rowsの値の変化

まとめ

データの更新は思ったより手間がかかります。

stateを直接いじるのに抵抗がない人はlodashを使わずに直接rowsを変更してもいいかもです。

DBでデータ管理するときは「更新」ボタンとかを作成してrowsをサーバに送って更新するとか。

onCellEditCommit時にサーバにデータを送って更新する手もあります。

その場合はセルの変更毎にサーバへの通信が発生しますが。

「Data Grid」は使うの面倒だな、もうちょっとどうにかできないだろうか。

「x-grid」のapiRefを使えばGridの状態や値を簡単に操作できるようなんですが、有料です。

無料の「Data Grid」を使うなら苦労しなさいってことなのかな、きっと有料機能への誘導だ!!

「Data Grid」でapiRefをhackして使えるようにする方法もあるようですが、できるだけホワイトで行きましょう。

ちなみに「onCellEditCommit」などの「on~」のprops内ならapiを使用できます。

とりあえず、追加・削除・更新ができるようになりました。

後はサーバ(DB)との連携だな。

ITエンジニアの転職

いまITエンジニアの需要は急拡大しています。
ITエンジニアの経験があれば好条件で転職することも難しくありません。

Geekly

☆ 支援ご協力のお願い ☆

この記事が「役に立った」と感じたら

投げ銭の「OFUSEで応援」で支援して頂けたら励みになります!

OFUSEのやり方(説明)

関連記事
記事特集