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

React+Typescript开发表格时列内容含string和JSX的类型问题如何解决?

实现方案

核心问题

问题核心是将业务逻辑用的原始纯数据和渲染层用的JSX元素混合存储在同一个字段数组中,既不符合单一职责设计原则,也会触发TypeScript的类型校验报错,就算显式声明联合类型,后续做排序、筛选时也需要额外做类型判断,增加冗余逻辑。


推荐落地方案(优先选择)

1. 拆分数据层与渲染层,数据层仅存纯字符串

所有用于排序、筛选的原始数据统一存储纯字符串类型,完全不涉及任何JSX相关逻辑,先定义清晰的TS类型:

// 原始数据层类型,仅存储纯文本业务数据
interface TableRowRaw {
  col1: string[]
  col2: string[]
  expanded: string[]
  // 其余自定义列字段
}

// 全局状态中仅存储原始数据和筛选状态
const [tableData, setTableData] = useState<TableRowRaw[]>([])
const [filterKeyword, setFilterKeyword] = useState<string>('')

2. 所有格式化、高亮逻辑放到渲染层封装

将JSX生成逻辑全部抽到渲染组件中,根据原始数据和当前筛选状态动态生成渲染内容,不需要修改原始数据:

// 封装通用高亮渲染组件
const HighlightText = ({ content, keyword }: { content: string; keyword: string }) => {
  if (!keyword) return <>{content}</>
  // 正则转义避免特殊字符报错
  const reg = new RegExp(`(${keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi')
  const fragments = content.split(reg)
  return <>
    {fragments.map((frag, idx) => 
      reg.test(frag) ? <mark key={idx}>{frag}</mark> : frag
    )}
  </>
}

// 表格列渲染时直接调用
const tableColumns = [
  {
    key: 'expanded',
    title: '展开内容',
    render: (row: TableRowRaw) => row.expanded.map((content, idx) => 
      <div key={idx}>
        <HighlightText content={content} keyword={filterKeyword} />
      </div>
    )
  }
  // 其余列渲染逻辑同理
]

方案优势

  • TypeScript类型完全清晰,无混合类型报错
  • 排序、筛选、导出等业务逻辑直接处理纯字符串,无需额外做类型兼容
  • 渲染逻辑与数据逻辑完全解耦,修改展示样式不需要改动数据层代码
  • 原始数据可复用,不会被渲染层逻辑污染

兼容方案(仅当确实需要混合存储时使用)

如果业务场景确实需要在数据中混合存储字符串和自定义JSX元素,可显式声明联合类型解决TS报错:

type CellItem = string | JSX.Element
type CellContent = CellItem[]

interface TableRow {
  col1: CellContent
  col2: CellContent
  expanded: CellContent
}

注意:该方案需要在做排序、筛选前,先判断数组元素类型,将JSX元素转换为对应的纯文本后再做逻辑处理,会增加额外的兼容代码,非必要不推荐使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:03