我试图在React JSX(其中ObjectRow是一个单独的组件)中执行以下操作:
<tbody>
for (var i=0; i < numrows; i++) {
<ObjectRow/>
}
</tbody>
我意识到并理解为什么这不是有效的JSX,因为JSX映射到函数调用。然而,由于来自模板领域,而且是JSX的新手,我不确定如何实现上述目标(多次添加组件)。
我试图在React JSX(其中ObjectRow是一个单独的组件)中执行以下操作:
<tbody>
for (var i=0; i < numrows; i++) {
<ObjectRow/>
}
</tbody>
我意识到并理解为什么这不是有效的JSX,因为JSX映射到函数调用。然而,由于来自模板领域,而且是JSX的新手,我不确定如何实现上述目标(多次添加组件)。
当前回答
@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>
其他回答
ES2015 Array.from,带有map函数+键
如果对.map()没有任何内容,可以使用Array.from()和map函数来重复元素:
<tbody>
{Array.from({ length: 5 }, (value, key) => <ObjectRow key={key} />)}
</tbody>
我找到了另一个解决方案提供:
<tbody>{this.getcontent()}</tbody>
还有一个单独的功能:
getcontent() {
const bodyarea = this.state.movies.map(movies => (
<tr key={movies._id}>
<td>{movies.title}</td>
<td>{movies.genre.name}</td>
<td>{movies.numberInStock}</td>
<td>{movies.publishDate}</td>
<td>
<button
onClick={this.deletMovie.bind(this, movies._id)}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
));
return bodyarea;
}
这个例子很容易解决许多问题。
有趣的是,人们如何使用更新的语法或不常见的方法来创建数组,从而给出“创造性”的答案。在我使用JSX的经验中,我见过这些技巧,只有经验不足的React程序员才会使用。
解决方案越简单,对未来的维护人员就越好。由于React是一个web框架,通常这种类型的(表)数据来自API。因此,最简单和最实用的方法是:
const tableRows = [
{id: 1, title: 'row1'},
{id: 2, title: 'row2'},
{id: 3, title: 'row3'}
]; // Data from the API (domain-driven names would be better of course)
...
return (
tableRows.map(row => <ObjectRow key={row.id} {...row} />)
);
在迭代数组和生成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>
)
}
您可以直接在JSX中执行相同的操作,使用map而不是for of循环:
render: function() {
const items = ['one', 'two', 'three'];
return (
<ul>
{items.map((value, index) => {
return <li key={index}>{value}</li>
})}
</ul>
)
}