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

时间:2017-12-20 14:38:18

标签: javascript reactjs typescript jsx

我有以下嵌套组件:

<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个项目,则会有5个TableColumn元素作为直接子项我的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元素数组。问题依然存在。

1 个答案:

答案 0 :(得分: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元素和一系列react元素。直接迭代子数组会给你这个。

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;
}