我试图在React JSX(其中ObjectRow是一个单独的组件)中执行以下操作:

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

我意识到并理解为什么这不是有效的JSX,因为JSX映射到函数调用。然而,由于来自模板领域,而且是JSX的新手,我不确定如何实现上述目标(多次添加组件)。


当前回答

在React中使用map是迭代数组的最佳实践。

为了防止ES6出现一些错误,React中使用了如下语法映射:

<tbody>
    {items.map((item, index) => <ObjectRow key={index} name={item.name} />)}
</tbody>

在这里,您调用一个组件<ObjectRow/>,因此不需要在箭头后面加括号。

但你也可以这样做:

{items.map((item, index) => (
    <ObjectRow key={index} name={item.name} />
))}

Or:

{items.map((item, index) => {
    // Here you can log 'item'
    return (
        <ObjectRow key={index} name={item.name} />
    )
})}

我这么说是因为如果在箭头后面加上括号“{}”,React将不会抛出错误,并显示白名单。

其他回答

请试试这个

<tbody>
   {Array.apply(0, Array(numrows)).map(function (x, i) {
     return <ObjectRow/>;
   })}
</tbody>

or

{[...Array(numrows)].map((x, i) =>
   <ObjectRow/>
)}

如果您习惯于Angular,并希望采用更像React的方法:

尝试使用这个带有自动哈希和可选trackBy的简单组件,类似于Angular。

用法:

<For items={items}>
    {item => <div>item</div>}
</For>

自定义键/轨迹依据:

<For items={items} trackBy={'name'}>
    {item => <div>item</div>}
</For>

定义:

export default class For<T> extends Component<{ items: T[], trackBy?: keyof T, children: (item: T) => React.ReactElement }, {}> {
    render() {
        return (
            <Fragment>
                {this.props.items.map((item: any, index) => <Fragment key={this.props.trackBy ?? item.id ?? index}>{this.props.children(item)}</Fragment>)}
            </Fragment>
        );
    }
}

React开发工具:

有多种方法可以做到这一点。JSX最终会被编译成JavaScript,所以只要你编写了有效的JavaScript,你就会很好。

我的回答旨在巩固这里已经介绍的所有精彩方式:

如果没有对象数组,只需输入行数:

在返回块中,创建一个Array并使用Array.prototype.map:

render() {
  return (
    <tbody>
      {Array(numrows).fill(null).map((value, index) => (
        <ObjectRow key={index}>
      ))}
    </tbody>
  );
}

在返回块之外,只需使用普通的JavaScript for循环:

render() {
  let rows = [];
  for (let i = 0; i < numrows; i++) {
    rows.push(<ObjectRow key={i}/>);
  }
  return (
    <tbody>{rows}</tbody>
  );
}

立即调用的函数表达式:

render() {
  return (
    <tbody>
      {(() => {
        let rows = [];
        for (let i = 0; i < numrows; i++) {
          rows.push(<ObjectRow key={i}/>);
        }
        return rows;
      })()}
    </tbody>
  );
}

如果您有一个对象数组

在返回块中,.map()将每个对象映射到<ObjectRow>组件:

render() {
  return (
    <tbody>
      {objectRows.map((row, index) => (
        <ObjectRow key={index} data={row} />
      ))}
    </tbody>
  );
}

在返回块之外,只需使用普通的JavaScript for循环:

render() {
  let rows = [];
  for (let i = 0; i < objectRows.length; i++) {
    rows.push(<ObjectRow key={i} data={objectRows[i]} />);
  }
  return (
    <tbody>{rows}</tbody>
  );
}

立即调用的函数表达式:

render() {
  return (
    <tbody>
      {(() => {
        const rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      })()}
    </tbody>
  );
}

也可以在返回块外部提取:

render: function() {
    var rows = [];
    for (var i = 0; i < numrows; i++) {
        rows.push(<ObjectRow key={i}/>);
    } 

    return (<tbody>{rows}</tbody>);
}

如果您真的想在JSX中使用for循环,可以使用IIFE。

<tbody>
  {
    (function () {
      const view = [];
      for (let i = 0; i < numrows; i++) {
        view.push(<ObjectRow key={i}/>);
      }
      return view;
    }())
  }
</tbody>