[React]テーブルのセルを結合する

## 概要
- Reactで配列をループさせてテーブルを描画する
- 特定の項目についてセルを結合させたい

## 作成イメージ
<img width="1197" alt="スクリーンショット 2020-02-05 15.01.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504173/027a21c1-2e46-0774-20f8-a2be625c15ac.png">

- 共通する項目についてセルを結合する

## 調べたこと
- [HTMLでtableタグのセルを結合する方法](https://www.tagindex.com/html_tag/table/td_span.html)

```html
<table border="3">
  <tr>
    <td rowspan="3">垂直方向の結合</td>
    <td>データ1</td>
  </tr>
  <tr>
    <td>データ2</td>
  </tr>
  <tr>
    <td>データ3</td>
  </tr>
</table>
```

## 実装
- 表示する配列

```javascript:src/constants/GroupList.js
import { nogizaka, keyakizaka, hinatazaka } from "./Color";

const groupList = [
  {
    id: 1,
    name: "乃木坂46",
    color: nogizaka.color,
    memberList: [
      {
        id: 1,
        name: "齋藤飛鳥",
        age: 21
      }
    ]
  },
  {
    id: 2,
    name: "欅坂46",
    color: keyakizaka.color,
    memberList: [
      {
        id: 1,
        name: "渡邉理佐",
        age: 21
      },
      {
        id: 2,
        name: "小林由依",
        age: 20
      }
    ]
  },
  {
    id: 3,
    name: "日向坂46",
    color: hinatazaka.color,
    memberList: [
      {
        id: 1,
        name: "齊藤京子",
        age: 22
      },
      {
        id: 2,
        name: "小坂菜緒",
        age: 17
      },
      {
        id: 3,
        name: "上村ひなの",
        age: 15
      }
    ]
  }
];

export default groupList;

```

- 表示するコンポーネント

```jsx:src/App.js
import React from "react";
import { Table } from "react-bootstrap";
import styled from "styled-components";
import groupList from "./constants/GroupList";

const ColorTr = styled.tr`
  color: ${({ color }) => color};
`;

function App() {
  return (
    <Table bordered>
      <thead>
        <tr>
          <th>グループ</th>
          <th>名前</th>
          <th>年齢</th>
        </tr>
      </thead>
      <tbody>
        {groupList.map(group =>
          group.memberList.map((member, i) =>
            i === 0 ? (
              <ColorTr key={member.id} color={group.color}>
                <td rowSpan={group.memberList.length}>{group.name}</td>
                <td>{member.name}</td>
                <td>{member.age}</td>
              </ColorTr>
            ) : (
              <ColorTr key={member.id} color={group.color}>
                <td>{member.name}</td>
                <td>{member.age}</td>
              </ColorTr>
            )
          )
        )}
      </tbody>
    </Table>
  );
}

export default App;

```
## 行ったこと
- 配列の個数を結合させる行数として`rowspan`の値に設定

```jsx:src/App.js
<td rowSpan={group.memberList.length}>{group.name}</td>
```

- ループさせる配列のインデックスをとり、先頭行の場合(インデックスが0の場合)とそうでない場合を分岐

```jsx:src/App.js
{groupList.map(group =>
  group.memberList.map((member, i) =>
    i === 0 ? (
      <ColorTr key={member.id} color={group.color}>
        <td rowSpan={group.memberList.length}>{group.name}</td>
　　　   // 省略
      </ColorTr>
    ) : (
　　　   // 省略
    )
  )
)}
```

## 終わりに
- とりあえず実現してみたけど何だか冗長・・・
- もっと良い方法をご存知の方いましたらコメントください

## 余談
本題とは全く関係ありませんが、今回使用したカラーコードはそれぞれ以下を参考にしています。

- [乃木坂46](https://nogizaka46cheer.sakamichi46.com/entry/2015/04/29/102910)
- [欅坂46](https://nogizaka46cheer.sakamichi46.com/entry/2019/03/18/232219)
- [日向坂46](https://nogizaka46cheer.sakamichi46.com/entry/2019/02/11/220004)