You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化React JS表格代码,实现高效、简洁与高可读性?

优化React角色权限表格代码建议

描述

我想要创建如下样式的表格:
表格示例图
我已经完成了开发,但觉得代码过于复杂不够简洁,希望能优化成更高效、可读且实用的版本。我正在学习React JS,目前还在努力掌握相关知识,任何帮助我都将十分感激。

当前代码

const FormCreateRole = ({ switches, onChange }) => {
  // Array for table header and its data
  const tableHeader = [
    "No",
    "Menu",
    "Sub Menu",
    "Lihat",
    "Tambah",
    "Ubah",
    "Hapus",
    "Export",
  ];

  const submenu = [
    ["-"],
    [
      "Akun Pengguna",
      "Grup & Kontrol Hak Akses Akun",
      "Antrian Pasien",
      "Rawat Jalan",
    ],
    ["Pemeriksaan Penunjang", "Rekam Medis", "Admisi Rawat Jalan"],
    ["Status dan Penempatan Kamar", "Transfer Pasien"],
  ];

  let i = 1;

  const tableDataMenu = [
    [i++, "Dashboard", submenu[0], "", null, null, null, ""],
    [i++, "Konfigurasi/Pengaturan", submenu[1], "", "", "", "", null],
    [i++, "Layanan Pasien", submenu[2], "", "", "", "", null],
    [i++, "Rawat Inap", submenu[3], "", "", "", "", null],
  ];
  // end Array data

  return (
    <Table className="table-responsive">
      <thead style={{ backgroundColor: "#ECEFF1" }}>
        <tr>
          {tableHeader.map((header, index) => (
            <th
              key={index}
              className="txt-blue-grey-700 base-md text-bold text-center"
              style={{ padding: "0.75rem" }}
            >
              {header}
            </th>
          ))}
        </tr>
      </thead>
      <tbody>
        {tableDataMenu.map((row, idx) => (
          <React.Fragment key={idx}>
            <tr>
              {row.slice(0, 2).map((cell, idx) => (
                <td key={idx} className="text-center">
                  {cell}
                </td>
              ))}
              <td>
                {row[2] && (
                  <div>
                    {row[2].map((sub, idx) => (
                      <div key={idx} className="mb-3">
                        {sub}
                      </div>
                    ))}
                  </div>
                )}
              </td>
              {row.slice(3).map((cell, idx) => {
                return (
                  <td key={idx}>
                    {row[2] &&
                      row[2].map((subIdx) => {
                        if (cell !== null) {
                          return (
                            <div key={subIdx} className="mb-3 text-center">
                              <Form.Check
                                type="switch"
                                id={`${subIdx}-${idx}`}
                                label=""
                                checked={switches[`action${idx}`]}
                                onChange={onChange}
                              />
                            </div>
                          );
                        }
                      })}
                  </td>
                );
              })}
            </tr>
          </React.Fragment>
        ))}
      </tbody>
    </Table>
  );
};

优化方案

1. 重构数据结构,提升可读性

把原本嵌套数组的结构改成对象数组,每个菜单的属性明确,数据含义一目了然:

// 定义权限动作常量,避免硬编码
const PERMISSIONS = ["Lihat", "Tambah", "Ubah", "Hapus", "Export"];

// 重构后的菜单数据
const menuData = [
  {
    id: 1,
    name: "Dashboard",
    subMenus: ["-"],
    permissions: [true, false, false, false, true] // 对应每个权限是否显示开关
  },
  {
    id: 2,
    name: "Konfigurasi/Pengaturan",
    subMenus: [
      "Akun Pengguna",
      "Grup & Kontrol Hak Akses Akun",
      "Antrian Pasien",
      "Rawat Jalan"
    ],
    permissions: [true, true, true, true, false]
  },
  {
    id: 3,
    name: "Layanan Pasien",
    subMenus: ["Pemeriksaan Penunjang", "Rekam Medis", "Admisi Rawat Jalan"],
    permissions: [true, true, true, true, false]
  },
  {
    id: 4,
    name: "Rawat Inap",
    subMenus: ["Status dan Penempatan Kamar", "Transfer Pasien"],
    permissions: [true, true, true, true, false]
  }
];

2. 提取子组件拆分重复逻辑

把重复的渲染逻辑拆成独立子组件,让主组件代码更简洁:

// 渲染子菜单的组件
const SubMenuCell = ({ subMenus }) => (
  <td>
    {subMenus.map((menu, idx) => (
      <div key={idx} className="mb-3">{menu}</div>
    ))}
  </td>
);

// 渲染权限开关的组件
const PermissionSwitchCell = ({ permission, subMenus, actionIndex, switches, onChange }) => {
  if (!permission) return <td></td>;
  
  return (
    <td>
      {subMenus.map((subMenu) => (
        <div key={subMenu} className="mb-3 text-center">
          <Form.Check
            type="switch"
            id={`${subMenu}-${actionIndex}`}
            label=""
            checked={switches[`action${actionIndex}`]}
            onChange={onChange}
          />
        </div>
      ))}
    </td>
  );
};

3. 简化主组件渲染逻辑

用重构后的数据和子组件,让主组件的渲染逻辑更清晰:

// 提取重复的表头样式常量
const TABLE_HEADER_CLASS = "txt-blue-grey-700 base-md text-bold text-center";
const TABLE_HEADER_STYLE = { padding: "0.75rem" };

const FormCreateRole = ({ switches, onChange }) => {
  return (
    <Table className="table-responsive">
      <thead style={{ backgroundColor: "#ECEFF1" }}>
        <tr>
          <th className={TABLE_HEADER_CLASS} style={TABLE_HEADER_STYLE}>No</th>
          <th className={TABLE_HEADER_CLASS} style={TABLE_HEADER_STYLE}>Menu</th>
          <th className={TABLE_HEADER_CLASS} style={TABLE_HEADER_STYLE}>Sub Menu</th>
          {PERMISSIONS.map((perm, idx) => (
            <th key={idx} className={TABLE_HEADER_CLASS} style={TABLE_HEADER_STYLE}>
              {perm}
            </th>
          ))}
        </tr>
      </thead>
      <tbody>
        {menuData.map((menu) => (
          <tr key={menu.id}>
            <td className="text-center">{menu.id}</td>
            <td className="text-center">{menu.name}</td>
            <SubMenuCell subMenus={menu.subMenus} />
            {menu.permissions.map((hasPermission, idx) => (
              <PermissionSwitchCell
                key={idx}
                permission={hasPermission}
                subMenus={menu.subMenus}
                actionIndex={idx}
                switches={switches}
                onChange={onChange}
              />
            ))}
          </tr>
        ))}
      </tbody>
    </Table>
  );
};

4. 其他细节优化

  • 移除不必要的React.Fragment,每个tr本身就是独立元素
  • 用菜单id、子菜单名称作为key,替代数组索引,提升React渲染稳定性
  • 提取重复样式为常量,减少代码冗余

内容的提问来源于stack exchange,提问作者github.arief

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:02:05