Reactアプリ内でjQueryプラグインのDataTables.jsを使うためのメモ。
ReactとjQueryはあまり相性が良くないので$
は最低限使うだけです。
合わせて使う方法からコンポーネント化まで。
React内でjQueryを使う
jQueryプラグインなので$が使えるようにする必要があります。
使っている管理システムでjQueryを追加します。
1 2 3 |
> npm install jquery > yarn add jquery > bower install jquery |
あとはlet $ = require('jquery');
で使えるようになります。
index.html内でCDNなどから読み込んでいる場合、コンポーネントではスコープ内で$
が見つからないためエラーになります。
代わりにwindow.$
を使う方法もありますが、ファイル先頭に/* global $ */
を追記することで$
がそのまま使えるようになります。
DataTablesを設定する
基本的にコンポーネントが準備完了したときにDataTable()
を呼び出す。
Reactライフサイクルは以前書いたものを参考にしました。
1 2 3 |
componentDidMount(){ $("#table1").DataTable() } |
render()で設定する
render内でTableを作ってしまう方法です。
細かい調整が可能でどんな形のデータでも工夫すれば表示可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
render() { let trs = []; this.state.someArray.forEach((v,i) => { trs.push( <tr key={i}> <td>{i}</td> <td>{v.A}</td> <td>{v.B}</td> <td>{v.C}</td> </tr> ); }); return( ... <table id="table1" className="cell-border compact stripe"> <thead><tr><th>#</th><th>AAA</th><th>BBB</th><th>CCC</th></tr></thead> <tbody>{trs}</tbody> </table> ... |
DataTable()で設定する
ヘッダやデータはDataTable内で設定可能です。
データが変な形でなければこちらの方がわかりやすい気がします。
1 2 3 4 5 6 7 8 9 |
$("#table1").DataTable({ data:data, columns: [ { title: "#", data: 'index' }, { title:"AAA", data: 'A' }, { title:"BBB", data: 'B' }, { title:"CCC", data: 'C' }, ] }); |
columns.data
はデータ配列内のオブジェクトがマップの時([{},{},...]
)のkeyを入れているので配列の時([[],[],...]
)は必要ありません。
元データにインデックスがない時はfor文でも書いて追加してもよさそうです。
1 |
data.forEach((e,i) => { e.index = i; }); |
データ表示はこの辺りを参考にしました(ajaxでデータをとってきてそのまま使う方法もあったけど使える状況がかなり限定されてるので試していない)。
コンポーネント化する
複数のテーブルを使いたいときに使いまわせるようコンポーネント化してみます。
とりあえず必要な分だけ適当に。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/* global $ */ import React from 'react'; class DataTable extends React.Component { $t = null; tableSet(){ this.$t = $("#"+this.props.table.id).DataTable({ data:this.props.table.data, columns: this.props.table.columns }); } componentDidMount(){ this.tableSet(); } componentDidUpdate(){ if(this.$t){ //this.$t.draw(); this.$t.destroy(false); this.tableSet(); } } render(){ const t = this.props.table; if(!t.class)t.class="cell-border compact stripe"; return( <table id={t.id} className={t.class}></table> ) } } export default DataTable; |
データ更新時はajax.reload()
かdraw()
で出来るように見えるんですが、どうしてもできなかったのでテーブル自体を作り直しています。
使う側ではこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 |
state = { table1:{id:"ta",data:[{a:"あ"}],columns:[{title:"A",data:"a"}]} } ... this.setState({table1:{id:"ta",data:[{a:"い"}],columns:[{title:"B",data:"a"}]}}) ... return( <DataTable table={this.state.table1}/> ) |
これよく考えなくてもReactとの相性悪い。
DataTablesは便利ですがReact寄りのテーブルを使った方がよさそうな気もします。