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

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

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


当前回答

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

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

其他回答

您可以尝试新的for of循环:

const apple = {
    color: 'red',
    size: 'medium',
    weight: 12,
    sugar: 10
}
for (const prop of apple.entries()){
    console.log(prop);
}

以下是几个示例:

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

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

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

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

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

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

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

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

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>])
        })
    }
}
function PriceList({ self }) {
    let p = 10000;
    let rows = [];
    for(let i=0; i<p; i=i+50) {
        let r = i + 50;
        rows.push(<Dropdown.Item key={i} onClick={() => self.setState({ searchPrice: `${i}-${r}` })}>{i}-{r} &#8378;</Dropdown.Item>);
    }
    return rows;
}

<PriceList self={this} />

在渲染或任何函数中,在返回之前,可以使用变量来存储JSX元素。就像这样-

const tbodyContent = [];
for (let i=0; i < numrows; i++) {
    tbodyContent.push(<ObjectRow/>);
}

在身体内部使用它,如下所示:

<tbody>
    {
        tbodyContent
    }
</tbody>

但我更喜欢map()而不是这个。