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

如何实现支持多数据结构与布局的可复用React Table组件?

可复用Table组件的TypeScript问题解决

背景

我正在开发一个包含大量表格的应用,这些表格外观大致相同,但部分表格的列配置、单元格内容存在差异,希望实现一个可在全应用复用的Table组件。目前已实现一个接收子组件和tableType的表格包装组件,根据tableType渲染列,但因数据结构和布局差异仍需为不同表格单独开发组件。不想过度使用条件渲染(如{tableType === "first" ? <TableCell>{item.name}</TableCell> : null}),因为这会导致代码难以维护和阅读。采用getCellComponent(tableType, value)类方案后效果很好,但遇到两个TypeScript错误需要解决。


问题1:为columnObj中的payload指定类型

场景

希望将columns props存储在变量中,但不知该为payload指定什么类型:

const columnObj = {
  firstName: {
    name: "First Name",
    width: "25%",
    accessor: (payload: any) => (
      <>
        <Avatar />
        {payload.who.nickname}
      </>
    )
  },
  // ...其他列配置
};

解决方案

  1. 先定义行数据的具体类型,比如针对该示例的业务数据结构:
// 定义嵌套的数据类型
interface UserInfo {
  nickname: string;
  // 补充其他需要的字段
}

// 定义单条行数据的类型
interface PayloadType {
  who: UserInfo;
  // 补充行数据的其他字段
}
  1. 定义列配置的通用类型,让列的accessor参数类型与表格行数据类型关联:
interface ColumnConfig<T> {
  name: string;
  width?: string;
  accessor: (rowData: T) => React.ReactNode;
}

type Columns<T> = Record<string, ColumnConfig<T>>;
  1. 为columnObj指定类型,TypeScript会自动校验accessor中的payload属性:
const columnObj: Columns<PayloadType> = {
  firstName: {
    name: "First Name",
    width: "25%",
    accessor: (payload) => (
      <>
        <Avatar />
        {payload.who.nickname}
      </>
    )
  },
  // ...其他列配置
};

问题2:修复行点击事件的TS错误

场景

想为表格添加行点击事件,通过onClick传递处理函数,但组件内绑定时报TS错误:

// 父组件调用
<MyTable<PayloadType2>
  columns={columnObj}
  payload={secondTableData}
  onClick={(id) => console.log("Row clicked:", id)}
/>

// 子组件内绑定代码
<TableBody>
  {payload.map((rowData, index) => {
    return (
      <TableRow key={index} 
       onClick={(id) => props.onClick(rowData.id)}> // 此处报TS错误
        // ...单元格渲染逻辑
      </TableRow>
    );
  })}
</TableBody>

解决方案

  1. 先在MyTable组件的Props类型中明确onClick的类型,关联行数据的ID字段类型:
interface MyTableProps<T> {
  columns: Columns<T>;
  payload: T[];
  onClick?: (rowId: T['id']) => void; // 假设行数据中存在id字段,取其类型
}
  1. 修正子组件内的onClick绑定:TableRow的onClick事件参数是React.MouseEvent,不是行ID,所以需要调整事件处理逻辑:
<TableRow 
  key={index} 
  onClick={() => props.onClick?.(rowData.id)}
>
  // ...单元格渲染逻辑
</TableRow>

如果需要传递事件对象,可改为:

<TableRow 
  key={index} 
  onClick={(e) => props.onClick?.(rowData.id, e)}
>
  // ...单元格渲染逻辑
</TableRow>

注意:需确保PayloadType2中确实包含id字段,若实际字段名不同,将T['id']替换为对应字段(如T['userId'])。


内容的提问来源于stack exchange,提问作者qweezz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:55:28