15
15

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.jsでtableの行が2行で1セットになるcomponentを作成する

Last updated at Posted at 2017-06-07

タイトル通りで、<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/

15
15
2

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
15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?