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

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

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


当前回答

有几个答案指向使用map语句。下面是一个完整的示例,它使用FeatureList组件中的迭代器基于一个称为features的JSON数据结构列出Feature组件。

const FeatureList = ({ features, onClickFeature, onClickLikes }) => (
  <div className="feature-list">
    {features.map(feature =>
      <Feature
        key={feature.id}
        {...feature}
        onClickFeature={() => onClickFeature(feature.id)}
        onClickLikes={() => onClickLikes(feature.id)}
      />
    )}
  </div>
); 

您可以在GitHub上查看完整的FeatureList代码。此处列出了特征夹具。

其他回答

我不确定这是否适用于您的情况,但通常地图是一个很好的答案。

如果这是使用for循环的代码:

<tbody>
    for (var i=0; i < objects.length; i++) {
        <ObjectRow obj={objects[i]} key={i}>
    }
</tbody>

你可以用地图这样写:

<tbody>
    {objects.map(function(object, i){
        return <ObjectRow obj={object} key={i} />;
    })}
</tbody>

ES6语法:

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

想象一下,你只是在调用JavaScript函数。不能在函数调用的参数所在的位置使用for循环:

return tbody(
    for (let i = 0; i < numrows; i++) {
        ObjectRow()
    } 
)

看看函数tbody是如何作为参数传递给for循环的——导致语法错误。

但您可以创建一个数组,然后将其作为参数传入:

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

使用JSX时,基本上可以使用相同的结构:

const rows = [];
for (let i = 0; i < numrows; i++) {
    // note: we are adding a key prop here to allow react to uniquely identify each
    // element in this array. see: https://reactjs.org/docs/lists-and-keys.html
    rows.push(<ObjectRow key={i} />);
}
return <tbody>{rows}</tbody>;

顺便说一下,我的JavaScript示例几乎与JSX的示例完全相同。玩Babel REPL,了解JSX的工作原理。

你必须用JSX写:

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

当我想添加一定数量的组件时,我使用助手函数。

定义一个返回JSX的函数:

const myExample = () => {
    let myArray = []
    for(let i = 0; i<5;i++) {
        myArray.push(<MyComponent/>)
    }
    return myArray
}

//... in JSX

<tbody>
    {myExample()}
</tbody>

你当然可以按照另一个答案的建议用.map来解决。如果您已经使用了Babel,可以考虑使用jsx控制语句。

它们需要一些设置,但我认为在可读性方面是值得的(特别是对于非React开发人员)。如果使用linter,还有eslint-plugin-jsx控制语句。