背景
リソースとってきて。
ループでゴリゴリ<table>
、<tr>
、<td>
配置して。
いちいちそんなことをやりたくなかった。
react table
とか、react datagrid
でググると良さげなコンポーネントは結構あるみたい。
けど、ソートとか、カラムの移動とか、そこまで仰々しいものは必要なかった。
なのでお勉強を兼ねて簡単なものを実装することにした。
やりたいこと
最低限、以下の2つが出来ればOK。
- dataProvider、dataFieldをプロパティに与えると、そこからテーブルを生成する
- デザインは外からcssを充てるスタイル
実装
コンポーネントはこんな感じで。
import React, { Component, PropTypes } from 'react';
/**
* データとフィールドを指定して<table>を描画する。
* 内部的にはシンプルなテーブルなので、デザインは外部からCSSにて操作する。
* @param {*} props - 利用元から渡されるプロパティ
* @example
* <DataGrid dataProvider={array of object}>
* <DataGridColumn dataField="dog"></DataGridColumn>
* <DataGridColumn dataField="cat"></DataGridColumn>
* <DataGridColumn dataField="rabbit"></DataGridColumn>
* </DataGrid>
*/
export const DataGrid = (props) => {
// DataGridColumnより、ヘッダを構築
const makeThead = (children) => {
let theadCols = children.map((child) => {
return <td>{child.props.dataField}</td>
});
return (
<thead>
<tr>
{theadCols}
</tr>
</thead>
);
};
// データプロバイダをリソースに、レコード部を構築
const makeTbody = (provider, children) => {
let tbodyRows = provider.map((item) => {
return (
<tr>
{
children.map((child) => {
return <td>{item[child.props.dataField]}</td>
})
}
</tr>
);
});
return (
<tbody>
{tbodyRows}
</tbody>
);
};
return (
<table className={props.className}>
{makeThead(props.children)}
{makeTbody(props.dataProvider, props.children)}
</table>
);
};
/**
* データグリッドのカラムを定義する。
* <DataGrid>の子要素として必ず1つ以上配置する。
* @param {*} props - 利用元から渡されるプロパティ
*/
export const DataGridColumn = (props) => {
// datafieldを受け取るのみ。
// 要素の描画は親コンポーネントにて実施
return null;
};
DataGrid.propTypes = {
dataProvider: PropTypes.arrayOf(PropTypes.object).isRequired,
children: PropTypes.node.isRequired,
className: PropTypes.string,
};
DataGridColumn.propTypes = {
dataField: PropTypes.string.isRequired,
};
呼び出し側はこんな感じで呼び出す。
import { DataGrid, DataGridColumn } from '../components/DataGrid';
const dp = [
{ dog: "犬", cat: "猫", rabbit: "兎" },
{ dog: "いぬ", cat: "ねこ", rabbit: "うさぎ" },
{ dog: "dog", cat: "cat", rabbit: "rabbit" },
];
return (
<DataGrid dataProvider={dp} className="mygrid">
<DataGridColumn dataField="dog"></DataGridColumn>
<DataGridColumn dataField="cat"></DataGridColumn>
<DataGridColumn dataField="rabbit"></DataGridColumn>
</DataGrid>
);
TODO
やっぱソートとかしたいし、ヘッダ固定でスクロールしたいね。
後者はcssで出来なくもないのかな。