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

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

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


当前回答

这是我迄今为止在大多数项目中使用的方法:

const length = 5;
...
<tbody>
    {Array.from({ length }).map((_,i) => (
        <ObjectRow key={i}/>
    ))}
</tbody>

其他回答

随着时间的推移,语言越来越成熟,我们经常会遇到这样的常见问题。问题是循环组件“n”次。

{[...new Array(n)].map((item, index) => <MyComponent key={index} />)}

其中,n-是要循环的次数。项将未定义,索引将照常。此外,ESLint不鼓励使用数组索引作为键。

但是,您的优点是不需要在之前初始化数组,最重要的是避免了for循环。。。

为了避免项目未定义带来的不便,您可以使用_,这样在进行linting时就会忽略它,并且不会引发任何linting错误,例如

{[...new Array(n)].map((_, index) => <MyComponent key={index} />)}

我用它就像

<tbody>
  { numrows ? (
     numrows.map(obj => { return <ObjectRow /> }) 
    ) : null
  }
</tbody>

@jacefarm如果我理解正确,您可以使用以下代码:

<tbody>
    { new Array(numrows).fill(<ObjectRow/>) } 
</tbody>

您可以使用以下代码:

<tbody>
   { new Array(numrows).fill('').map((item, ind) => <ObjectRow key={ind}/>) } 
</tbody>

还有这个:

<tbody>
    new Array(numrows).fill(ObjectRow).map((Item, ind) => <Item key={ind}/>)
</tbody>

您需要向数组中添加元素并渲染元素数组。这有助于减少重新渲染组件所需的时间。

下面是一些可能有用的粗略代码:

MyClass extends Component {
    constructor() {
        super(props)
        this.state = { elements: [] }
    }
    render() {
        return (<tbody>{this.state.elements}<tbody>)
    }
    add() {
        /*
         * The line below is a cheap way of adding to an array in the state.
         * 1) Add <tr> to this.state.elements
         * 2) Trigger a lifecycle update.
         */
        this.setState({
            elements: this.state.elements.concat([<tr key={elements.length}><td>Element</td></tr>])
        })
    }
}

我倾向于采用编程逻辑发生在render返回值之外的方法。这有助于保持实际呈现的内容易于理解。

所以我可能会做一些类似的事情:

import _ from 'lodash';

...

const TableBody = ({ objects }) => {
  const objectRows = objects.map(obj => <ObjectRow object={obj} />);      

  return <tbody>{objectRows}</tbody>;
} 

诚然,这是一个很小的代码量,内联它可能会很好。