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

如何在Grommet DataTable中处理数组类型数据?

在Grommet DataTable中实现数组类型单元格的展开折叠功能

问题背景

我有如下结构的数组类型数据:

{
    customer: [
        'BANANA',
        'Banana',
        'banana',
        'republic of banana'
    ],
    somethingelse: ['ABC','123','DEF']
}

在常规Grommet Table中,我可以把数组的首个元素作为单元格标题,再添加展开箭头展示数组的其余元素,但不清楚如何在Grommet DataTable的单元格层面实现这个效果。

常规Grommet Table的实现代码

<TableCell scope="row" pad={{ left: '2px', right: '3px' }}>
  <TextInput name="tags" size="xsmall" />
</TableCell>
</TableRow>
{searchResults.length > 0 &&
  searchResults.map((searchResult, index) => (
    <TableRow key={index}>
      <TableCell>
        <Box direction="row">
          <Text size="xsmall">{searchResult.customer[0]}</Text>
          {searchResult.customer.length > 1 && (
            <Button
              plain
              hoverIndicator={false}
              icon={
                isExpanded[index] ? (
                  <FormDown size="18px" />
                ) : (
                  <FormNext size="18px" />
                )
              }
              onClick={() => toggleOpen(index)}
            />
          )}
        </Box>
        <Box>
          {isExpanded[index] && listElements(searchResult.customer)}
        </Box>
      </TableCell>

当前DataTable的代码(待改造)

return (
  <Form value={formData} onSubmit={onSubmit} onChange={onChange}>
    ...
      <DataTable
        fill
        border={{ body: 'bottom' }}
        paginate
        columns={columns}
        data={searchResults}
        select={select}
        onClickRow={(e) => console.log(e.datum)}
        onSelect={() => {}}
        step={8}
        rowDetails={(row) => {             // 我可使用rowDetails展开显示部分数据,但如何实现1. 将数组的[0]元素作为标题;2. 应用到行/表格的所有单元格。
          for (const cell in row) {
            // if (cell.length > 1) {
            //   return listElements(cell);
            // }
            console.log(cell);
          }
        }}
        ...
       />
       ...
  </Form>
);

解决方案

要在Grommet DataTable中实现该功能,需要通过自定义列渲染器控制单元格内容,同时维护每行的展开状态:

1. 维护展开状态

在组件内部添加状态记录每行的展开情况:

const [expandedRows, setExpandedRows] = useState({});

const toggleExpand = (rowId) => {
  setExpandedRows(prev => ({
    ...prev,
    [rowId]: !prev[rowId]
  }));
};

2. 配置自定义列

在columns配置中,为包含数组的字段指定render函数,实现首元素展示+展开箭头的逻辑:

const columns = [
  {
    property: 'customer',
    header: 'Customer',
    render: ({ customer, index }) => (
      <Box>
        <Box direction="row" align="center" gap="small">
          <Text size="xsmall">{customer[0]}</Text>
          {customer.length > 1 && (
            <Button
              plain
              hoverIndicator={false}
              icon={expandedRows[index] ? <FormDown size="18px" /> : <FormNext size="18px" />}
              onClick={() => toggleExpand(index)}
            />
          )}
        </Box>
        {expandedRows[index] && (
          <Box margin={{ top: 'small' }}>
            {customer.slice(1).map((item, idx) => (
              <Text key={idx} size="xsmall" margin={{ left: 'medium' }}>{item}</Text>
            ))}
          </Box>
        )}
      </Box>
    )
  },
  {
    property: 'somethingelse',
    header: 'Something Else',
    render: ({ somethingelse, index }) => (
      <Box>
        <Box direction="row" align="center" gap="small">
          <Text size="xsmall">{somethingelse[0]}</Text>
          {somethingelse.length > 1 && (
            <Button
              plain
              hoverIndicator={false}
              icon={expandedRows[index] ? <FormDown size="18px" /> : <FormNext size="18px" />}
              onClick={() => toggleExpand(index)}
            />
          )}
        </Box>
        {expandedRows[index] && (
          <Box margin={{ top: 'small' }}>
            {somethingelse.slice(1).map((item, idx) => (
              <Text key={idx} size="xsmall" margin={{ left: 'medium' }}>{item}</Text>
            ))}
          </Box>
        )}
      </Box>
    )
  }
];

3. 更新DataTable组件

去掉rowDetails,直接使用配置好的columns即可:

<DataTable
  fill
  border={{ body: 'bottom' }}
  paginate
  columns={columns}
  data={searchResults.map((item, idx) => ({ ...item, index: idx }))} // 给每行添加index用于追踪展开状态
  select={select}
  onClickRow={(e) => console.log(e.datum)}
  onSelect={() => {}}
  step={8}
/>

补充说明

  • 若数据本身有唯一ID,可替换index作为展开状态的绑定键,避免分页或数据更新导致的状态混乱。
  • 如需实现单元格级别的独立展开(不同字段各自控制展开),可将expandedRows的键设计为${rowId}-${property}的形式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:50:30