我试图在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的新手,我不确定如何实现上述目标(多次添加组件)。
当前回答
您可以在React for循环中使用.map()。
<tbody>
{ newArray.map(() => <ObjectRow />) }
</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;
}
这个例子很容易解决许多问题。
以下是您可以在React中通过迭代对象数组或普通数组实现的可能解决方案
const rows = [];
const numrows = [{"id" : 01, "name" : "abc"}];
numrows.map((data, i) => {
rows.push(<ObjectRow key={data.id} name={data.name}/>);
});
<tbody>
{ rows }
</tbody>
Or
const rows = [];
const numrows = [1,2,3,4,5];
for(let i=1, i <= numrows.length; i++){
rows.push(<ObjectRow key={numrows[i]} />);
};
<tbody>
{ rows }
</tbody>
最近几天,我熟悉的一种更好的迭代对象数组的方法是直接在渲染中使用.map,可以返回也可以不返回:
.map带返回
const numrows = [{"id" : 01, "name" : "abc"}];
<tbody>
{numrows.map(data=> {
return <ObjectRow key={data.id} name={data.name}/>
})}
</tbody>
.map不返回
const numrows = [{"id" : 01, "name" : "abc"}];
<tbody>
{numrows.map(data=> (
<ObjectRow key={data.id} name={data.name}/>
))}
</tbody>
Array.from是最好的方法。如果您想创建一个具有一定长度的JSX数组。
function App() {
return (
<tbody>
{Array.from({ length: 10 }, (_, key) => (
<ObjectRow {...{ key }} />
))}
</tbody>
);
}
上面的示例适用于没有数组的情况,因此,如果您有数组,则应在JSX中将其映射为:
function App() {
return (
<tbody>
{list.map((item, key) => (
<ObjectRow {...{ key }} />
))}
</tbody>
);
}
如果您还没有像@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
在所有情况下,关键属性都会减轻开发构建的警告,但在孩子中无法访问。如果希望子级中的索引可用,可以传递额外的属性。有关讨论,请参见列表和键。
有趣的是,人们如何使用更新的语法或不常见的方法来创建数组,从而给出“创造性”的答案。在我使用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} />)
);