嵌入式表达式呈现为数组而不是单个元素

问题描述 投票:0回答:1

我有以下嵌套组件:

<Table data={records}>
    <TableColumn field="code">Code</TableColumn>
    {columns.map((column, i) => (
      <TableColumn key={column} field={column}>
        {column}
      </TableColumn>
    ))}
</Table>

我的Table组件扩展了这个界面:

export interface TableProps {
  data: any[];
  children: React.ReactElement<TableColumnProps>[];
}

在该组件中,我使用以下函数遍历TableColumn的子项(Table的实例):

getDefaultSortColumn() {
    let col = this.props.children[0].props.field;
    this.props.children.forEach((column: React.ReactElement<TableColumnProps>) => {
      if (column.props.sortDefault) {
        col = column.props.field;
      }
    });
    return col as string;
  }

执行此操作时,我的期望是使用map()的JSX表达式已执行,如果columns中有4个项目,则在我的TableColumn中将有5个Table元素作为直接子项。相反,第二个元素实际上是一个元素数组本身。

为什么我的代码不能仅将TableColumn元素渲染为我的Table的直接子元素?

更新似乎做以下工作:

  getDefaultSortColumn() {
    let col = this.props.children[0].props.field;
    this.props.children.forEach((child: React.ReactElement<any>) => {
      if (Array.isArray(child)) {
        child.forEach((column: React.ReactElement<O3TableColumnProps>) => {
          if (column.props.sortDefault) {
            col = column.props.field;
          }
        });
      }
      else if (child.props.sortDefault) {
        col = child.props.field;
      }
    });
    return col as string;
  }

但我不想这样访问我的孩子,测试该项是否是我想要的TableColumnProps元素类型或TableColumnProps元素的数组。问题仍然存在。

javascript reactjs typescript jsx
1个回答
1
投票

你的JSX编译成如下所示的东西:

const TableColumn = React.createElement('div', { field: 'code' }, 'Code')
const Table = React.createElement('div', {}, [
  TableColumn,
  columns.map((column, i) =>
    React.createElement('div', { key: column, field: column }, column),
  ),
])

你可以看到Table的孩子们包括一个反应元素和一系列反应元素。直接迭代子数组会给你这样的。

React为这类东西提供了顶级API - React.Children - 在你的迭代中使用React.Children.mapReact.Children.forEach遍历子数组。

调整后的功能如下:

getDefaultSortColumn() {
  let col = this.props.children[0].props.field;
  React.Children.forEach(this.props.children, (column) => {
    if (column.props.sortDefault) {
      col = column.props.field;
    }
  });
  return col;
}
© www.soinside.com 2019 - 2024. All rights reserved.