本文翻译自:Loop inside React JSX
I'm trying to do something like the following in React JSX
(where ObjectRow is a separate component): 我正在React JSX
尝试执行以下操作(其中ObjectRow是一个单独的组件):
for (var i=0; i < numrows; i++) {
}
I realize and understand why this isn't valid JSX
, since JSX
maps to function calls. 我意识到并理解为什么这不是有效的JSX
,因为JSX
映射到函数调用。 However, coming from template land and being new to JSX
, I am unsure how I would achieve the above (adding a component multiple times). 但是,由于来自模板领域并且是JSX
新手,所以我不确定如何实现上述目标(多次添加组件)。
参考:https://stackoom.com/question/1XzLW/在React-JSX内部循环
Think of it like you're just calling JavaScript functions. 就像您只是在调用JavaScript函数一样。 You can't use a for
loop where the arguments to a function call would go: 您不能在for
循环中使用函数调用的参数:
return tbody(
for (var i = 0; i < numrows; i++) {
ObjectRow()
}
)
See how the function tbody
is being passed a for
loop as an argument, and of course that's a syntax error. 了解如何将函数tbody
作为参数传递给for
循环,这当然是语法错误。
But you can make an array, and then pass that in as an argument: 但是您可以创建一个数组,然后将其作为参数传递:
var rows = [];
for (var i = 0; i < numrows; i++) {
rows.push(ObjectRow());
}
return tbody(rows);
You can use basically the same structure when working with JSX: 使用JSX时,可以使用基本相同的结构:
var rows = [];
for (var i = 0; i < numrows; i++) {
// note: we add 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( );
}
return {rows};
Incidentally, my JavaScript example is almost exactly what that example of JSX transforms into. 顺便说一句,我的JavaScript示例几乎就是该JSX示例转换成的示例。 Play around with Babel REPL to get a feel for how JSX works. 与Babel REPL一起玩,以了解JSX的工作方式。
Not sure if this will work for your situation, but often map is a good answer. 不知道这是否适合您的情况,但通常使用地图是个不错的选择。
If this was your code with the for loop: 如果这是带有for循环的代码:
for (var i=0; i < objects.length; i++) {
}
You could write it like this with map : 您可以使用map这样写:
{objects.map(function(object, i){
return ;
})}
ES6 syntax: ES6语法:
{objects.map((object, i) => )}
I know this is an old thread, but you might want to checkout React Templates , which does let you use jsx-style templates in react, with a few directives (such as rt-repeat). 我知道这是一个旧线程,但是您可能想签出React模板 ,它确实允许您在React中使用jsx样式的模板,并带有一些指令(例如rt-repeat)。
Your example, if you used react-templates, would be: 如果使用react-templates,那么您的示例将是:
If you don't already have an array to map()
like @FakeRainBrigand's answer, and want to inline this so the source layout corresponds to the output closer than @SophieAlpert's answer: 如果您还没有像@FakeRainBrigand的答案那样的map()
数组,并且想要内联,那么源布局将比@SophieAlpert的答案更接近输出:
http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview
{[...Array(10)].map((x, i) =>
)}
Re: transpiling with Babel, its caveats page says that Array.from
is required for spread, but at present ( v5.8.23
) that does not seem to be the case when spreading an actual Array
. 回复:使用Babel进行转译时,其警告页面说,传播需要Array.from
,但目前( v5.8.23
)在传播实际Array
时似乎并非如此。 I have a documentation issue open to clarify that. 我有一个文档问题需要澄清。 But use at your own risk or polyfill. 但是使用后果自负或使用polyfill。
Array.apply
{Array.apply(0, Array(10)).map(function (x, i) {
return ;
})}
http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview
{(function (rows, i, len) {
while (++i <= len) {
rows.push( )
}
return rows;
})([], 0, 10)}
Keep the source layout corresponding to the output, but make the inlined part more compact: 保持源布局与输出相对应,但使内联部分更紧凑:
render: function () {
var rows = [], i = 0, len = 10;
while (++i <= len) rows.push(i);
return (
{rows.map(function (i) {
return ;
})}
);
}
Array
methods 使用ES2015语法和Array
方法 With Array.prototype.fill
you could do this as an alternative to using spread as illustrated above: 借助Array.prototype.fill
您可以执行上述操作来替代使用点差:
{Array(10).fill(1).map((el, i) =>
)}
(I think you could actually omit any argument to fill()
, but I'm not 100% on that.) Thanks to @FakeRainBrigand for correcting my mistake in an earlier version of the fill()
solution (see revisions). (我认为您实际上可以省略fill()
任何参数,但我并不是100%这样。)感谢@FakeRainBrigand在更早版本的fill()
解决方案中纠正了我的错误(请参阅修订)。
key
In all cases the key
attr alleviates a warning with the development build, but isn't accessible in the child. 在所有情况下, key
属性都会减轻开发版本的警告,但在子级中无法访问。 You can pass an extra attr if you want the index available in the child. 如果希望子级中的索引可用,则可以传递一个额外的attr。 See Lists and Keys for discussion. 请参阅列表和键进行讨论。
Your JSX code will compile into pure JavaScript code, any tags will be replaced by ReactElement
objects. 您的JSX代码将编译为纯JavaScript代码,任何标签都将被ReactElement
对象替换。 In JavaScript, you cannot call a function multiple times to collect their returned variables. 在JavaScript中,不能多次调用函数来收集其返回的变量。
It is illegal, the only way is to use an array to store the function returned variables. 这是非法的,唯一的方法是使用数组存储函数返回的变量。
Or you can use Array.prototype.map
which is available since JavaScript ES5 to handle this situation. 或者,您可以使用Array.prototype.map
( 从JavaScript ES5开始提供)来处理这种情况。
Maybe we can write other compiler to recreate a new JSX syntax to implement a repeat function just like Angular's ng-repeat
. 也许我们可以编写其他编译器来重新创建新的JSX语法以实现重复功能,就像Angular的ng-repeat
。