タイトル通りで、<table>
で2行で1セットとなるような行を表示をしたい場合の1つの方法として。
【お知らせ】
今は React.Fragment
があるのでこのような記述は不要になりました。(一応この記事は記念に残しておきます・・・)
課題
React.createClass({
render: function() {
return (
<tr><td>Item 1</td></tr>
<tr><td>Item 2</td></tr>
);
}
});
現時点ではrenderは、単一要素でラップしてreturnする制約があるので、<tr></tr>
を2つ返すような上記の記述は出来ない。tableでなければ、適当に <div></div>
等で囲めば良いのだけど、table行なのでこの方法が使えない。
それならば、2行をまとめて <tbody></tbody>
で囲めば良いのでは?と安直に考えたものの、validateDOMNesting
の警告が出てしまった。(HTML的にはtbodyが複数出現するのは許容されているはずなのだけど、React的にはNGっぽい)
解決法
まずはサンプルとして、1行ずつ表示させる一般的なtableの例。
const data = [
{ id: 1, firstName: 'John', lastName: 'Doe' },
{ id: 2, firstName: 'Clark', lastName: 'Kent' }
];
class Table extends React.Component {
render() {
const rowComponents = this.generateRows();
return (
<table>
<thead>
<th>First Name</th>
<th>Last Name</th>
</thead>
<tbody> {rowComponents} </tbody>
</table>
);
}
generateRows() {
const data = this.props.data;
return data.map((item) => {
// -----👇👇👇注目ポイント
return (
<tr key={item.id}>
<td>{item.firstName}</td>
</tr>
);
// -----👆👆👆注目ポイント
});
}
}
React.render(<Table data={data}/>, document.getElementById('example'));
これを、2行ずつ表示させるように修正する。
const data = [
{ id: 1, firstName: 'John', lastName: 'Doe' },
{ id: 2, firstName: 'Clark', lastName: 'Kent' }
];
class Table extends React.Component {
render() {
const rowComponents = this.generateRows();
return (
<table>
<thead>
<th>First Name</th>
<th>Last Name</th>
</thead>
<tbody> {rowComponents} </tbody>
</table>
);
}
generateRows() {
const data = this.props.data;
return data.map((item) => {
// -----👇👇👇注目ポイント
return ([
<tr key={'firstRow_' + item.id}>
<td>{item.firstName}</td><td>{item.lastName}</td>
</tr>,
<tr key={'secondRow_' + item.id}>
<td>{item.firstName}</td><td>{item.lastName}</td>
</tr>
]);
// -----👆👆👆注目ポイント
});
}
}
React.render(<Table data={data}/>, document.getElementById('example'));
変更したのは、「注目ポイント」と書いた return()
の箇所だけ。配列で返すようにして、keyの値がユニークになるように手を加えたのみ。(1つ目 </tr>
の後ろのカンマを忘れずに)
jsfiddle にもソースを置いたので色々試したい方はどうぞ。
http://jsfiddle.net/kiharu/m38L2tyy/