React + Material-UIの画面にmaterial-tableを導入してみた
こんにちは、CX 事業本部の若槻です。
Reactで使えるMaterial-UIをベースとしたデータテーブルコンポーネントとしてmaterial-tableというOSSがあります。
material-tableを使うことにより、Reactの標準のデータテーブルコンポーネントよりもフィルター、検索、ソートなどのテーブル機能を拡張することができます。
今回は、このmaterial-tableをReact + Material-UIで作った画面に導入してみました。
アウトプット
次のようなmaterial-tableのデータテーブルを持ったページを作成します。
環境
OS、Node,js、npm、TypeScriptのバージョンは次の通りです。
% sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.6
BuildVersion: 19G73
% node -v
v12.14.0
% npm -v
6.13.4
% npx tsc --version
Version 3.9.7
作成
進め方としては、まず以下の記事の内容でReact + Material-UIの画面を作成します。(文中での「元記事」はこの記事を指します)
その次に作成した画面に対してmaterial-tableを導入します。
React + Material-UIの画面作成
Reactアプリを新規作成します。
% npx create-react-app react-material-ui-sample --typescript
必要なディレクトリを作成します。
% cd react-material-ui-sample
% mkdir src/components
% mkdir src/components/templates
% mkdir src/components/pages
トップページと商品ページを作成します。(作成内容は元記事を参照)
% touch src/components/pages/HomePage.tsx
% touch src/components/pages/ProductPage.tsx
ページのルーティングに必要なライブラリをインストールします。
% npm install --save react-router-dom
% npm install --save-dev @types/react-router-dom
App.tsx
を編集してルーティングを実装します。(編集内容は元記事を参照)
% vi App.tsx
すると編集後のApp.tsx
で次のエラーが出ました。
Could not find a declaration file for module 'react'. '/Users/wakatsuki.ryuta/react-material-ui-sample/node_modules/react/index.js' implicitly has an 'any' type.
If the 'react' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react`ts(7016)
事例を探したところ次の記事が参考になりました。
tsconfig.json
に"noImplicitAny": false,
を追加したらエラーは解消されました。
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"noImplicitAny": false
},
"include": ["src"]
}
Material-UIをインストールします。
% npm install --save @material-ui/core @material-ui/icons
public/index.html
のヘッダーにGoogle日本語フォントのCDNのURLを追加します。(編集内容は元記事を参照)
% vi public/index.html
ページのテンプレートを作成します。(作成内容は元記事を参照)
% touch src/components/templates/GenericTemplate.tsx
トップページと商品ページを編集してテンプレートを適用します。(編集内容は元記事を参照)
% vi src/components/pages/HomePage.tsx
% vi src/components/pages/ProductPage.tsx
商品ページを編集してTableコンポーネントを導入します。(編集内容は元記事を参照)
% vi src/components/pages/ProductPage.tsx
Reactアプリを起動します。
npm start
http://localhost:3000/products
にアクセスします。
React + Material-UIにより、次のようなMaterial-UI標準のデータテーブルを持ったページを作成することができました。
material-tableの導入
次にmaterial-tableによる商品ページを作成します。
material-tableのGet Startedを参考に、必要なライブラリをインストールします。なお@material-ui/core
は前項でインストール済みです。
material-table
をインストールします。
% npm install --save [email protected]
src/components/pages/ProductPage.tsx
を次のように変更します。
import React from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import MaterialTable from 'material-table';
import GenericTemplate from '../templates/GenericTemplate';
type Props = {} & RouteComponentProps<{}>;
const ProductPage: React.FC<Props> = (props) => {
return (
<GenericTemplate title={'商品ページ'}>
<MaterialTable
columns={[
{ title: '商品名', field: 'itemName' },
{ title: 'カテゴリー', field: 'category' },
{ title: '重量(g)', field: 'weight' },
{ title: '価格(円)', field: 'price' },
]}
data={[
{ itemName: 'チョコレート', category: 'お菓子', weight: 100, price: 120 },
{ itemName: 'ケーキ', category: 'お菓子', weight: 400, price: 480 },
{ itemName: 'りんご', category: 'フルーツ', weight: 500, price: 360 },
{ itemName: 'バナナ', category: 'フルーツ', weight: 200, price: 300 },
{ itemName: 'みかん', category: 'フルーツ', weight: 250, price: 180 },
]}
options={{
showTitle: false,
}}
/>
</GenericTemplate>
);
};
export default withRouter(ProductPage);
material-tableの定義は<MaterialTable/>
タグの中で行います。タグの中で設定可能なプロパティは下記ページに一覧があります。
http://localhost:3000/products
にアクセスします。
次のようなmaterial-tableのデータテーブルを持ったページを作成することができました。
おわりに
React + Material-UIの画面にmaterial-tableを導入してみました。
material-tableは、Material-UI標準のデータテーブルと比べて微調整をしなくても既定でデザインが良い感じですし、便利な機能の追加も容易なので便利ですね。
個人的には今までどこまでがMateril-UIでどこまでがmaterial-tableの機能なのかイマイチ理解できてなかったので整理できて良かったです。
参考
以上