7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React + json-server + ag-Grid で色々と試してみた [ag-Grid基礎編]

Last updated at Posted at 2021-02-25

はじめに

この記事は、前回記事 の続編です。環境周りの情報や、モック API の作成方法はそちらに記載していますので、お時間のある方は併せて読んで頂けると嬉しいです。

フロントエンドの構築には React と Material-UI を使っていますが、この記事の目的は ag-Grid の機能や実装方法を紹介することなので、ここでは取り扱いません。また、掲載しているソースコードは、説明を分かりやすくするために直接的な関係がない部分を思い切って省略しているのでご注意ください。

それでは行ってみましょう!

テーブル定義

うーん、実にシンプルですね。divAgGridReact を囲うだけです。ag-Grid のテーマは divclassName 属性で指定します。このとき指定したテーマの css を一緒に import しておくのがポイントです。標準でいくつかのテーマが提供されているので ここ を参考にしてください。

import { AgGridReact } from "ag-grid-react";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css"; // ← ポイント!

const AgGrid = () => {
  return (
    <div className="ag-theme-alpine" style={{ height: "100%", width: "100%" }}>
      <AgGridReact
        // プロパティを設定
        domLayout={"autoHeight"}  // テーブルの高さを自動調整
      />
    </div>
  );
};

列定義

次に、列定義を見ていきましょう。基本は columnDef に1列ずつ定義をしていきます。ただ、この方法だと列数が多くなった場合に管理が煩雑になるのは目に見えてますね。例えば、全列に検索フィルタを付けたいとか、数値系の項目は右寄せしたいとか…。考えただけでもゾッとします。

そういったときに便利なのが columnTypesdefaultColDef です。columnTypes は同種の列に対して、defaultColDef は全ての列に対して共通の設定を適用することができます。

そして、定義は columnDef > columnTypes > defaultColDef の順で優先されるので、適切なレベルで設定を行うことで、定義を減らしメンテナンス性を上げることができます。

ちなみに、columnTypes には rightAligned という右寄せの定義が標準で用意されているので、自分でわざわざ定義をする必要はありません。なかなか気が利いていますね!

列定義に関しては ここ や Columns セクション下の関連ドキュメントを見てもらうと、さらに色々な事が分かると思います。

const AgGrid = () => {

  // 全列に共通の定義
  const defaultColDef = {
    sortable: true,  // ソート可
    editable: true,  // 編集可
  };

  // 列タイプの定義
  const columnTypes = {
    nonEditableColumn: { editable: false },  // 編集不可
  };

  // 個別列の定義
  const columnDefs = [
    {
      headerName: "Group", // 列のグルーピング
      children: [
        {
          headerName: "Column1",
          field: "col1",
          type: "nonEditableColumn", // 編集不可が優先
        },
        {
          headerName: "Column2",
          field: "col2",
          type: "rightAligned", // 右寄せ
          sortable: false, // ソート不可が優先
        },
      ],
    },
    {
      headerName: "Column3",
      field: "col3",
    },
  ];

  return (
    <div className="ag-theme-alpine" style={{ height: "100%", width: "100%" }}>
      <AgGridReact
        // それぞれの定義を指定
        defaultColDef={defaultColDef}
        columnTypes={columnTypes}
        columnDefs={columnDefs}
      />
    </div>
  );
};

データ反映

データの反映にはいくつかの方法がありますが、ここでは Grid API を使った方法を試していきます。Grid API は onGridReady のコールバック関数として渡される Grid オブジェクトからアクセスできます。

今回は 前回 作った REST API から取得したデータをテーブルに反映したいので、applyTransaction メソッドを使用します。この引数に取得したデータを渡すのですが、データを add プロパティに設定するところがポイントです。他にも updateremove プロパティーがあるのですが、何が起こるかは何となく想像できますよね。

Grid API にも様々な API が定義されているので、詳しくは ここ を見てください。

const AgGrid = () => {
    
  // ag-Grid の準備完了後に呼ばれるコールバック関数
  const onGridReady = (grid) => {
    (async () => {
      grid.api.applyTransaction({ add: await getData() });  // データを追加
    })();
  };

  // REST API からデータを取得
  const getData = async () => {
    let { data } = await axios.get("http://localhost:3001/users");
    return data;
  };

  return (
    <div className="ag-theme-alpine" style={{ height: "100%", width: "100%" }}>
      <AgGridReact
        // コールバック関数を指定
        onGridReady={onGridReady}
      />
    </div>
  );
};

applyTransaction に渡すデータはこんなイメージです。データと列のマッピングは 列定義 で行った field の指定によって行われます。

[
  {
    "col1": "value0-1",
    "col2": "value0-2",
    "col3": "value0-3"
  },
  {
    "col1": "value1-1",
    "col2": "value1-2",
    "col3": "value1-3"
  }
]

動作確認

ここまでの内容を組み合わせると下のような画面が完成します。各列の状態と併せて確認してみて下さい。

  • Column1 : 編集不可 / ソート可
  • Column2 : 編集可能 / ソート不可 / 右寄せ
  • Column3 : 編集可能 / ソート可

image.png

完成ソースコード
import { AgGridReact } from "ag-grid-react";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css"; // ← ポイント!
import axios from "axios";
import { Grid } from "@material-ui/core";

const AgGrid = () => {

  // ag-Grid の準備完了後に呼ばれるコールバック関数
  const onGridReady = (grid) => {
    (async () => {
      grid.api.applyTransaction({ add: await getData() }); // データを追加
    })();
  };

  // REST API からデータを取得
  const getData = async () => {
    let { data } = await axios.get("http://localhost:3001/samples");
    return data;
  };

  // 全列に共通の定義
  const defaultColDef = {
    sortable: true, // ソート可
    editable: true, // 編集可
  };

  // 列タイプの定義
  const columnTypes = {
    nonEditableColumn: { editable: false }, // 編集不可
  };

  // 個別列の定義
  const columnDefs = [
    {
      headerName: "Group", // 列のグルーピング
      children: [
        {
          headerName: "Column1",
          field: "col1",
          type: "nonEditableColumn", // 編集不可が優先
        },
        {
          headerName: "Column2",
          field: "col2",
          type: "rightAligned", // 右寄せ
          sortable: false, // ソート不可が優先
        },
      ],
    },
    {
      headerName: "Column3",
      field: "col3",
    },
  ];

  return (
    <>
      <Grid container spacing={1}>
        <Grid item xs={12}>
          <div
            className="ag-theme-alpine"
            style={{ height: "100%", width: "100%" }}
          >
            <AgGridReact
              defaultColDef={defaultColDef}
              columnTypes={columnTypes}
              columnDefs={columnDefs}
              onGridReady={onGridReady}
              domLayout={"autoHeight"}
            />
          </div>
        </Grid>
      </Grid>
    </>
  );
};

export default AgGrid;

まとめ

定義する列数や複雑さにもよりますが、わずか数十行のコードで REST API からのデータ反映に加え、機能と見栄えを両立したテーブルが作成できました。また、Reactでコンポーネント化がされているのでコードの理解もしやすいです。

API ドキュメントなどを読みながら実装を進めたので、実際にはそこそこ時間がかかってしまったのですが、一度理解すればこの程度の画面は数時間で実装できると思います。

次回は応用編と位置づけて、もう少し深堀りして色々な機能を紹介していきたいと思います!
(例によって、長くなったので分割させてください🙏)

参考リンク

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?