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

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

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


当前回答

只需使用带有ES6语法的map Array方法:

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

不要忘记密钥属性。

其他回答

在迭代数组和生成JSX元素方面有很多解决方案。所有这些都很好,但都直接在循环中使用了索引。我们建议使用数据中的唯一id作为键,但如果数组中的每个对象没有唯一id,我们将使用索引作为键,但是不建议直接使用索引作为密钥。

还有一件事,为什么我们选择.map,但为什么不选择foEach,因为.map返回一个新数组。现在有很多不同的方法。

下面使用.map的不同版本详细说明了如何使用唯一键以及如何使用.map循环JSX元素。

当从数据中返回单个JSX元素和唯一id作为密钥版本时,.map不返回:

const {objects} = this.state;

<tbody>
    {objects.map(object => <ObjectRow obj={object} key={object.id} />)}
</tbody>

将数据中的多个JSX元素和唯一id作为密钥版本返回时,不返回.map

const {objects} = this.state;

<tbody>
    {objects.map(object => (
        <div key={object.id}>
            <ObjectRow obj={object} />
        </div>
    ))}
</tbody>

当将单个JSX元素和索引作为键版本返回时,.map没有返回:

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => <ObjectRow obj={object} key={`Key${index}`} />)}
</tbody>

当返回多个JSX元素和索引作为密钥版本时,.map没有返回:

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => (
        <div key={`Key${index}`}>
            <ObjectRow obj={object} />
        </div>
    ))}
</tbody>

.map,当返回多个JSX元素和索引作为键版本时返回:

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => {
        return (
            <div key={`Key${index}`}>
                <ObjectRow obj={object} />
            </div>
        )
    })}
</tbody>

将数据中的多个JSX元素和唯一id作为密钥版本返回时,使用return的.map:

const {objects} = this.state;

<tbody>
    {objects.map(object => {
        return (
            <div key={object.id}>
                <ObjectRow obj={object} />
            </div>
        )
    })}
</tbody>

另一种方式是

render() {
  const {objects} = this.state;
  const objectItems = objects.map(object => {
       return (
           <div key={object.id}>
               <ObjectRow obj={object} />
           </div>
       )
  })
  return(
      <div>
          <tbody>
              {objectItems}
          </tbody>
      </div>
   )
}

如果您还没有像@FakeRainBrigand的答案那样的要映射()的数组,并且希望内联该数组,以使源布局与比@SophieAlpert的答案更接近的输出相对应:

使用ES2015(ES6)语法(扩展和箭头函数)

http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview

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

回复:使用Babel进行传输时,其警告页面显示Array.from是传播所必需的,但目前(v5.2.23)在传播实际的Array时似乎并非如此。我有一个文件问题需要澄清。但请自行承担风险或使用polyfill。

香草ES5

阵列应用

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

内联IIFE

http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview

<tbody>
  {(function (rows, i, len) {
    while (++i <= len) {
      rows.push(<ObjectRow key={i} />)
    }
    return rows;
  })([], 0, 10)}
</tbody>

其他答案的技术组合

保持与输出相对应的源布局,但使内联部分更紧凑:

render: function () {
  var rows = [], i = 0, len = 10;
  while (++i <= len) rows.push(i);

  return (
    <tbody>
      {rows.map(function (i) {
        return <ObjectRow key={i} index={i} />;
      })}
    </tbody>
  );
}

使用ES2015语法和数组方法

对于Array.prototype.fill,您可以这样做,作为使用如上所示的排列的替代方法:

<tbody>
  {Array(10).fill(1).map((el, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

(我认为你实际上可以省略fill()的任何参数,但我不是100%。)感谢@FakeRainBrigand在fill()解决方案的早期版本中纠正了我的错误(请参阅修订版)。

key

在所有情况下,关键属性都会减轻开发构建的警告,但在孩子中无法访问。如果希望子级中的索引可用,可以传递额外的属性。有关讨论,请参见列表和键。

甚至这段代码也能完成同样的工作。

<tbody>
   {array.map(i => 
      <ObjectRow key={i.id} name={i.name} />
   )}
</tbody>

您可以从numRows创建数组并映射它

像这样的东西:

        <tbody>
           {Array.from({ length: numrows }).map((_,i)=><ObjectRow key={i}/>)
        </tbody>

您的JSX代码将编译成纯JavaScript代码,任何标记都将被ReactElement对象替换。在JavaScript中,不能多次调用函数来收集返回的变量。

这是非法的,唯一的方法是使用数组来存储函数返回的变量。

或者您可以使用Array.prototype.map来处理这种情况,Array.prototype.map自JavaScriptES5以来就可用。

也许我们可以编写其他编译器来重新创建一个新的JSX语法来实现一个repeat函数,就像Angular的ng repeat一样。