Help us understand the problem. What is going on with this article?

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

概要

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

作成イメージ

スクリーンショット 2020-02-05 15.01.31.png

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

調べたこと

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

実装

  • 表示する配列
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;

  • 表示するコンポーネント
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の値に設定
src/App.js
<td rowSpan={group.memberList.length}>{group.name}</td>
  • ループさせる配列のインデックスをとり、先頭行の場合(インデックスが0の場合)とそうでない場合を分岐
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>
    ) : (
      // 省略
    )
  )
)}

終わりに

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

余談

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

mdc
”自己研鑽のサイクル”を応援するコミュニティです。外の世界に発信&フィードバックを受け、コミュニティの仲間と共に頑張りましょう。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした