Loop inside React JSX
我尝试在react jsx中执行如下操作(其中objectrow是一个单独的组件):
1 2 3 4 5 | <tbody> for (var i=0; i < numrows; i++) { <ObjectRow/> } </tbody> |
我了解并理解为什么这不是有效的JSX,因为JSX映射到函数调用。但是,由于来自模板Land并且是JSX的新手,我不确定如何实现上述目标(多次添加组件)。
- 需要注意的是,在JSX中,需要在JavaScript语法周围使用标记。这可能有助于facebook.github.io/react/docs/&hellip;。
let todos = this.props.todos.map((todo) => {return {todo.title}</h1>})
想象一下,你只是在调用javascript函数。不能使用
1 2 3 4 5 | return tbody( for (var i = 0; i < numrows; i++) { ObjectRow() } ) |
看看函数
但您可以创建一个数组,然后将其作为参数传入:
1 2 3 4 5 | var rows = []; for (var i = 0; i < numrows; i++) { rows.push(ObjectRow()); } return tbody(rows); |
使用JSX时,可以使用基本相同的结构:
1 2 3 4 5 6 7 | 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(<ObjectRow key={i} />); } return <tbody>{rows}</tbody>; |
顺便说一下,我的javascript示例几乎就是JSX示例转换成的。与BabelRepl一起玩,了解JSX的工作原理。
- 编译器可能已经更改了,因为这个示例似乎没有在JSX编译器中编译,但是使用下面fakerainbrigand答案中的map似乎编译正确。
- 我可以保证最后一个示例仍然在最新的JSX编译器上正确编译。
- 这很管用。Fakerainbrigand的答案适用于简单的数组迭代,但对于不能使用
map 的情况(例如,没有存储在变量中的集合),这个答案是必须的。 - 注意,如果
ObjectRow 有任何属性,不要将属性值放在引号中,否则它们将不会被插值; 而不是 也一样。 - 很完美!工作正常,我使用的是字符串concat
rows += - react需要有效地更新dom,在这种情况下,父级应该为每个子级分配一个
key 。参考:facebook.github.io/react/docs/&hellip; - @后台:这是不同的JSX。
- 这是一个很好的例子,但是它遗漏了一些重要的位,比如
key 属性,以及一种代码样式,这种样式并没有真正用于反应代码基中。请将这个答案stackoverflow.com/questions/22876978/loop-inside-react-jsx/&hellip;视为正确答案。 - 嘿,为什么可以使用array.map?
- 同意@Okonetchnikov。这个答案是误导性的,并且会导致其他问题,因为
key 被设置为数组索引。 - 对于使用typescript的,声明应该是
let rows: JSX.Element[] = []; 。 - @因为
的子级接受一系列反应组件作为子级。map 的回调返回ObjectRow s,就是这样。换句话说,因为对map 的调用是表达式(允许),而for 循环是语句(不允许)。- 对于我来说,使用JSX的重要时刻是,当我记起它删除了什么并意识到上下文是一个函数调用时,我只限于表达式。然后,我不仅理解什么是允许的,而且更好地理解我应该生产什么。(有关详细信息,请参阅stackoverflow.com/a/12703326/749227)
- thinkster.io/tutorials/reac&zwnj;&8203;t中的迭代和呈现循环
- 索菲厄珀特,我是个反应迟钝的新手。我不明白为什么我们不在数组中调用map,并在map中使用唯一键呈现objectrow组件??
- 这很好,但我们可以说,为了便于阅读,循环需要位于JSX内部。
不确定这是否适用于您的情况,但通常地图是一个很好的答案。
如果这是带有for循环的代码:
1
2
3
4
5<tbody>
for (var i=0; i < objects.length; i++) {
<ObjectRow obj={objects[i]} key={i}>
}
</tbody>你可以用地图这样写:
1
2
3
4
5<tbody>
{objects.map(function(object, i){
return <ObjectRow obj={object} key={i} />;
})}
</tbody>ES6语法:
1
2
3<tbody>
{objects.map((object, i) => <ObjectRow obj={object} key={i} />)}
</tbody>- 如果迭代器是一个数组,映射就更有意义;如果它是一个数字,则for循环是合适的。
- 使用Reactivfy的ES6支持或Babel。
- + 1。我甚至把它和一个ul(无序列表)一起使用。使用typescript的
-
{objects.map((object:string,i:number)=>{ return
- {object}</li> })} </ul>
- 这很好,但不能在对象上映射。为此,我将使用
for..in 。 - @Damon迭代对象以创建元素几乎总是不好的,但您可以执行
Object.keys(obj).map(...) - 是啊?redux倾向于为那些有键的东西推荐对象,而这些键经常需要调用它们。如果你不去继承、添加函数和诸如此类的废话……(我猜在ES6中,这是一个映射,而不是一个对象。)关于keys().map的好观点。少一些疯疯癫癫的。
- 请记住,使用object.keys时,键的顺序是任意的。我发现单独存储键的顺序效果很好,如果需要的话,还可以使用对象文本的顺序。这样我就可以编写像
this.props.order.map((k)=> 这样的代码。) - @tgrr实际上是插入顺序,在所有实现和规范中都是如此(除了整数键之外,它们是按数字顺序排列的)。
- @我读到的fakerainbrigand说object.keys提供的可枚举顺序与…的顺序相同,后者是任意顺序。除此之外,我很少发现插入顺序足够灵活,并且有明确的单独排序允许重新排序等。
- 好答案。我花了一些时间才意识到我忘记了
return 关键字,因为它是一个函数。我将对此发表评论,希望其他人不会犯同样的错误。 - @Damon您也可以在对象上使用lodash
map 到map - ES6语法对我很有用,我喜欢它的形式。
如果您还没有像@fakerainbrigand's answer那样的到EDOCX1[3]的数组,并且想要内联它,那么源布局对应的输出比@sophiealter's answer更接近:
使用ES2015(ES6)语法(spread和arrow函数)http://plnkr.co/edit/mfqfwodvy8dkqkokiegv?P=预览
1
2
3
4
5<tbody>
{[...Array(10)].map((x, i) =>
<ObjectRow key={i} />
)}
</tbody>回复:巴别塔说,它的警告页面说,扩展需要
香草ES5Array.from ,但目前(v5.8.23 )在实际扩展Array 时似乎不是这样。我有一个文件问题需要澄清。但使用时要自行承担风险。Array.apply 1
2
3
4
5<tbody>
{Array.apply(0, Array(10)).map(function (x, i) {
return <ObjectRow key={i} />;
})}
</tbody>内联iIFE
http://plnkr.co/edit/4kqjdtzd4w69g8suu2ht?P=预览
1
2
3
4
5
6
7
8<tbody>
{(function (rows, i, len) {
while (++i <= len) {
rows.push(<ObjectRow key={i} />)
}
return rows;
})([], 0, 10)}
</tbody>结合其他答案的技巧
保持与输出对应的源布局,但使内联部分更紧凑:
1
2
3
4
5
6
7
8
9
10
11
12render: 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 方法使用
Array.prototype.fill ,您可以这样做作为使用spread的替代方法,如上图所示:1
2
3
4
5<tbody>
{Array(10).fill(1).map((el, i) =>
<ObjectRow key={i} />
)}
</tbody>(我认为你可以忽略任何关于
fill() 的论点,但我不是100%的。)感谢@fakerainbrigand在早期版本的fill() 解决方案中纠正了我的错误(见修订版)。key 在所有情况下,
key attr都可以通过开发构建减轻警告,但在儿童中不可访问。如果您希望子级中的索引可用,可以传递额外的attr。请参阅列表和键进行讨论。- 那么
yield 呢?当我们有了生成器时,将元素推入中间数组有点难看。他们工作吗? - @马克,我不知道发电机真的适用于这里。在JSX上下文中,实现这一点的关键是返回数组的表达式。所以,如果你想以某种方式使用一个生成器,你很可能无论如何都会传播它,而且它可能比这里基于ES2015的解决方案更冗长。
- 怎么会更详细?为什么JSX不接受任何一个ITerable,而不仅仅是数组?
- @标记它确实比我使用的(es5)iife示例不那么冗长,但它比
[...Array(x)].map(() => 版本要冗长得多,我认为这是最优雅的版本,也是我为什么使用它的原因。回复:第二个问题,这是一个很好的观点。似乎没有任何关于JSX的东西可以排除它,所以它取决于转换后的JSX的另一个消费者对孩子们的论点做了什么反应,我不能不看来源就说出来。你知道吗?这是一个有趣的问题。)) - @法克兰布里甘德!感谢您指出我不正确的
Array.prototype.fill() 用法。我添加了一个正确的版本。 - 我认为map是更好的选择之一,因为它非常适合JSX,并且相当不错的浏览器支持。
- 有没有办法在循环中保持
this 引用相同?这样我就可以使用this.state 或this.props 。谢谢。 - @是的,有多种方法。如果使用箭头函数,情况就已经是这样了。使用正则函数时,可以将
thisArg 作为第二个参数传递给map() 。等。 - 最后一个江户一〔11〕是狡猾的。简洁/直观。感谢您介绍各种方法。
- 酷,谢谢你@corysimmons。您是指带省略的数组排列(
[,...Array(10)] )还是带fill() 的数组排列? - 填充(同样,它不需要任何参数),但使用这些参数后,我认为我喜欢不带逗号的排列。为什么逗号?它是旧浏览器的gotcha还是什么?
- @科里西莫恩很酷,谢谢你提供的关于
fill() 的信息。我现在还记得,我犹豫的原因是关于参数的可选性如何在ES规范中表示的一个问题(有时必须研究一下)。逗号只是消除数组元素的一种方法——在本例中是第一种方法。如果希望索引的长度为1.. - @JMM你为什么要做
key={i + 1} ?0 不是有效的密钥吗? - 您可以通过在数组上调用.keys()来避免未使用的
x 元素,即{[...Array(10).keys()].map(i => 。摘自stackoverflow.com/a/33352604/37147 - @安迪,是的,这是一个很好的观点,我已经更新了这个来反映这一点。不久前我打算这样做,他们在文档中有一个具体的例子显示了这一点。今天我检查的时候,他们好像把文件改写了很多。他们仍然有一个例子来说明这一点,但现在他们也不遗余力地将
key 描述为一个字符串(但随后不一致地显示显式地将值强制转换为字符串,或只是将其设置为一个数字&175; u()175;)。 - @Janaagaard是的,这也是一个不错的选择,但实际上它比使用未使用的
x 的版本更加冗长,即使您不需要在单个参数周围使用parens(它需要ES6方法)。不过,这是一个很好的选择,尤其是我给出的.fill() 示例的一个很好的替代方案。它们在冗长方面非常相似,但可以说,.keys() 方式概念上更清晰,更容易理解。 - 哦,创建一个空数组
[...Array(10)].map 只是为了循环,看起来更像是一个黑客
只需使用带有ES6语法的map array方法:
1
2
3<tbody>
{items.map(item => <ObjectRow key={item.id} name={item.name} />)}
</tbody>不要忘记
key 属性。使用数组映射函数是遍历元素数组并根据它们在react中创建组件的非常常见的方法,这是一种很好的循环方法,这是在JSX中执行循环的非常有效和整洁的方法,这不是唯一的方法,而是首选的方法。另外,不要忘记根据需要为每个迭代都有一个唯一的键。map函数从0创建唯一索引,但不建议使用生成的索引,但如果您的值是唯一的或有唯一键,则可以使用它们:
1
2
3<tbody>
{numrows.map(x=> <ObjectRow key={x.id} />)}
</tbody>此外,如果您不熟悉数组上的map函数,那么MDN中的几行代码也会:
map calls a provided callback function once for each element in an
array, in order, and constructs a new array from the results. callback
is invoked only for indexes of the array which have assigned values,
including undefined. It is not called for missing elements of the
array (that is, indexes that have never been set, which have been
deleted or which have never been assigned a value).callback is invoked with three arguments: the value of the element,
the index of the element, and the Array object being traversed.If a thisArg parameter is provided to map, it will be used as
callback's this value. Otherwise, the value undefined will be used as
its this value. This value ultimately observable by the callback is
determined according to the usual rules for determining the this seen
by a function.map does not mutate the array on which it is called (although
callback, if invoked, may do so).Array#map 不是异步的!
如果您已经在使用lodash,那么
_.times 函数就很方便了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import React, { Component } from 'react';
import Select from './Select';
import _ from 'lodash';
export default class App extends Component {
render() {
return (
{_.times(3, i =>
<li key={i}>
<Select onSelect={this.onSelect}>
<option value="1">bacon</option>
<option value="2">cheez</option>
</Select>
</li>
)}
);
}
}- 如果不包括像lodash这样的库,array.prototype.map可能是一个很好的选择。developer.mozilla.org/en-us/docs/web/javascript/reference/&hellip;。
- @只有当你已经有了一个数组的时候,伊莎格雷才会这样做。有时候你只想重复几次。
- 当然可以!很多不同的方法当然取决于实际数据。我发现,在我们的开发过程中,我们常常能够适应映射,因为如果建模,数据是如何进行的。使用罗达什的好例子!顺便问一下,您是否使用属性初始值设定项语法将方法绑定到组件?
- @伊莎赫格雷,我想他们刚刚被称为ES6方法定义。
还可以在返回块外提取:
1
2
3
4
5
6
7
8render: function() {
var rows = [];
for (var i = 0; i < numrows; i++) {
rows.push(<ObjectRow key={i}/>);
}
return (<tbody>{rows}</tbody>);
}我知道这是一个旧线程,但您可能需要签出http://wix.github.io/react-templates/,它允许您在react中使用JSX样式的模板,并带有一些指令(如rt repeat)。
如果使用React模板,则示例如下:
1
2
3<tbody>
<ObjectRow rt-repeat="obj in objects"/>
</tbody>- 为什么在纯javascript已经提供了各种for循环或array.prototype.map方法的解决方案时使用附加库来解决这个问题?我自己已经在我的当前项目中使用了两种简单的javascript方法,它们都很好地工作。如果可能的话,习惯使用简单的javascript方法可以帮助我提高我的javascript技能。我只在某些问题难以找到解决方案时使用其他库,例如使用React路由器进行路由。
如果numrow是一个数组,那么它非常简单。
1
2
3<tbody>
{numrows.map(item => <ObjectRow />)}
</tbody>react中的数组数据类型非常好,数组可以支持新的数组,并支持过滤、减少等。
- 这不是一个体面的答案,因为它没有使用钥匙。
有几个答案指向使用
map 语句。下面是一个完整的示例,使用FeatureList组件中的迭代器根据一个称为Features的JSON数据结构列出功能组件。1
2
3
4
5
6
7
8
9
10
11
12const FeatureList = ({ features, onClickFeature, onClickLikes }) => (
{features.map(feature =>
<Feature
key={feature.id}
{...feature}
onClickFeature={() => onClickFeature(feature.id)}
onClickLikes={() => onClickLikes(feature.id)}
/>
)}
);您可以在GitHub上查看完整的功能列表代码。这里列出了特征装置。
- 在处理JSON数据时,例如使用fetch API从数据库中检索数据时,我依赖于使用array.prototype.map方法。这是一种方便且行之有效的方法。
假设我们在您的状态中有一系列项目:
1
2
3
4
5
6
7[{name:"item1", id: 1}, {name:"item2", id: 2}, {name:"item3", id: 3}]
<tbody>
{this.state.items.map((item) => {
<ObjectRow key={item.id} name={item.name} />
})}
</tbody>- 我想你可能需要把地图(项目)后面的去掉,这对我来说很有用。
有多种方法可以做到这一点。JSX最终会被编译成JavaScript,只要你写的是有效的JavaScript,你就会很好。
我的答案旨在巩固这里已经呈现的所有精彩方式:
如果没有对象数组,只需行数:
在
return 块中,创建一个Array 并使用Array.prototype.map :1
2
3
4
5
6
7
8
9render() {
return (
<tbody>
{Array(numrows).fill(null).map((value, index) => (
<ObjectRow key={index}>
))}
</tbody>
);
}在
return 块之外,只需使用普通的javascript for循环:1
2
3
4
5
6
7
8
9render() {
let rows = [];
for (let i = 0; i < numrows; i++) {
rows.push(<ObjectRow key={i}/>);
}
return (
<tbody>{rows}</tbody>
);
}立即调用的函数表达式:
1
2
3
4
5
6
7
8
9
10
11
12
13render() {
return (
<tbody>
{() => {
let rows = [];
for (let i = 0; i < numrows; i++) {
rows.push(<ObjectRow key={i}/>);
}
return rows;
}}
</tbody>
);
}如果有对象数组
在
return 块中,.map() 每个对象都指向 组件:1
2
3
4
5
6
7
8
9render() {
return (
<tbody>
{objectRows.map((row, index) => (
<ObjectRow key={index} data={row} />
))}
</tbody>
);
}在
return 块之外,只需使用普通的javascript for循环:1
2
3
4
5
6
7
8
9render() {
let rows = [];
for (let i = 0; i < objectRows.length; i++) {
rows.push(<ObjectRow key={i} data={objectRows[i]} />);
}
return (
<tbody>{rows}</tbody>
);
}立即调用的函数表达式:
1
2
3
4
5
6
7
8
9
10
11
12
13render() {
return (
<tbody>
{(() => {
const rows = [];
for (let i = 0; i < objectRows.length; i++) {
rows.push(<ObjectRow key={i} data={objectRows[i]} />);
}
return rows;
})()}
</tbody>
);
}- 很好的答案:各种各样的技术,都只使用简单的javascript,它显示了javascript的力量,这得益于它执行类似任务的各种方式。
…或者您也可以准备一个对象数组并将其映射到一个函数以获得所需的输出。我更喜欢这个,因为它可以帮助我保持良好的编码实践,在返回呈现的过程中没有逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17render() {
const mapItem = [];
for(let i =0;i<item.length;i++)
mapItem.push(i);
const singleItem => (item, index) {
// item the single item in the array
// the index of the item in the array
// can implement any logic here
return (
<ObjectRow/>
)
}
return(
<tbody>{mapItem.map(singleItem)}</tbody>
)
}只需使用
.map() 循环您的集合,并从每个迭代中返回带有道具的 项。假设
objects 是一个数组…1
2
3<tbody>
{ objects.map((obj, index) => <ObjectRow obj={ obj } key={ index }/> ) }
</tbody>ES2015/Babel的一种可能性是使用生成器函数创建一个JSX数组:
1
2
3
4
5
6
7
8
9
10
11
12
13function* jsxLoop(times, callback)
{
for(var i = 0; i < times; ++i)
yield callback(i);
}
...
<tbody>
{[...jsxLoop(numrows, i =>
<ObjectRow key={i}/>
)]}
</tbody>我用这个:
1
2
3gridItems = this.state.applications.map(app =>
<ApplicationItem key={app.Id} app={app } />
);警察:别忘了钥匙,否则会有很多警告!
- 或者,如果您的项没有
.Id 属性(如items.map( (item, index) => 属性),则使用数组索引。{item}</Foo>
如果您选择转换render方法的内部返回(),最简单的选项是使用map()方法。使用map()函数将数组映射为JSX语法,如下所示(使用ES6语法)。
父组件内部:
{ objectArray.map((object, index) =>) }
请注意添加到您的子组件中的
key 属性。如果没有提供key属性,则可以在控制台上看到以下警告。Warning: Each child in an array or iterator should have
a unique"key" prop.现在,在ObjectRow组件中,您可以从对象的属性访问该对象。
在ObjectRow组件内
const { object } = this.props 或
const object = this.props.object 这将获取从父组件传递给ObjectRow组件中的变量
object 的对象。现在,您可以根据您的目的,将该对象中的值吐出。参考文献:
javascript中的map()方法
ECMA脚本6或ES6
ES2015数组。从映射函数+键开始如果您对
.map() 没有任何内容,可以使用Array.from() 和mapFn 来重复元素:1
2
3<tbody>
{Array.from({ length: 5 }, (v, k) => <ObjectRow key={k} />)}
</tbody>我倾向于一种编程逻辑发生在
render 的返回值之外的方法。这有助于保持实际的东西容易摸索。所以我可能会这样做:
1
2
3
4
5
6
7
8
9import _ from 'lodash';
...
const TableBody = ({ objects }) => {
const objectRows = objects.map(obj => <ObjectRow object={obj} />);
return <tbody>{objectRows}</tbody>;
}诚然,这是如此之少的代码,嵌入它可能会很好地工作。
- 用于迭代对象的Lodash地图的大风扇。我倾向于使用
import { map } from 'lodash' ,因此,如果您不需要所有lodash函数,您就不会导入它们。 - 这些天我们甚至不需要罗达什地图——直接在阵列上绘制。
- 是的,但是不能循环使用ES6
map() 的对象,只能使用数组。我就是这么说的,罗达什是一个很好的循环超过一个物体。 - 我以为你的意思是"以东"〔9〕就像一张单子,我的错。
JSX代码将编译成纯JavaScript代码,任何标记都将被
ReactElement 对象替换。在javascript中,不能多次调用函数来收集返回的变量。这是非法的,唯一的方法是使用数组来存储函数返回的变量。
或者您可以使用
Array.prototype.map ,这是自JavaScriptES5以来可用的,用于处理这种情况。也许我们可以编写其他编译器来重新创建一个新的JSX语法来实现重复函数,就像Angular的
ng-repeat 一样。你当然可以用另一个答案建议的.map来解决问题。如果您已经使用了babel,那么可以考虑使用JSX控制语句。它们需要一些设置,但我认为在可读性方面是值得的(特别是对于非反应开发人员)。如果您使用linter,还有eslint plugin jsx控制语句
这可以通过多种方式实现。
- 如上所述,在
return 之前,将所有元素存储在数组中 return 内回路方法1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25let container =[];
let arr = [1,2,3] //can be anything array, object
arr.forEach((val,index)=>{
container.push(
val
)
/**
* 1. All loop generated elements require a key
* 2. only one parent element can be placed in Array
* e.g. container.push(
val
this will throw error
)
**/
});
return (
any things goes here
{container}
)方法2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18return(
any things goes here
{(()=>{
let container =[];
let arr = [1,2,3] //can be anything array, object
arr.forEach((val,index)=>{
container.push(
val
)
});
return container;
})()}
)- 是啊。在我当前的项目中,我使用方法1,即使用array.prototype、foreach()方法创建HTML select元素,该元素由数据库中的数据填充。但是,我更可能用array.prototype.map()方法替换它们,因为map方法看起来更紧凑(代码更少)。
- 在创建HTML select元素时,我首先想到的是类似的技术,所以我使用它,尽管我使用foreach()方法。但是当我重新阅读关于列表和键主题的react文档时,我发现它们使用了map()方法,这里的几个答案也显示了这一点。这让我觉得这是首选的方式。我同意,因为它看起来更紧凑(代码更少)。
- 更具可读性。
- 在react中,在render中使用匿名函数被认为不是一个好的实践,因为这些函数需要在每次重新渲染时被重新创建或丢弃。
- 在本例中,它不会影响性能。
- 如果您希望这个关键字等于类本身,那么只需将函数转换为fat arrow。
- 虽然这段代码可以回答这个问题,但是提供关于如何和/或为什么解决这个问题的额外上下文可以提高答案的长期价值。
- 这会打破的。您需要关闭objectrow标记,并且应该在map回调中返回一些内容。
- 你能为你的代码添加一些解释吗?
要循环多次并返回,可以在
1 2 3 4 5 | <tbody> { Array.from(Array(i)).map(() => <ObjectRow />) } </tbody> |
其中
我用它像
1 2 3 4 5 | <tbody> { numrows ? ( numrows.map(obj => { return <ObjectRow /> }) ) : null} </tbody> |
这里有一个简单的解决方案。
1 2 3 4 5 6 7 | var Object_rows=[]; for (var i=0; i < numrows; i++) { Object_rows.push(<ObjectRow/>) } <tbody> {Object_rows} </tbody> |
不需要映射和复杂代码。只需将行推送到数组并返回值即可呈现。
由于您在JSX代码中编写JavaScript语法,因此需要将您的JavaScript用大括号括起来。
1 2 3 4 5 6 7 8 9 10 | row = () => { var rows = []; for (let i = 0; i<numrows; i++) { rows.push(<ObjectRow/>); } return rows; } <tbody> {this.row()} </tbody> |
您还可以使用自调用函数:
1 2 3 4 5 6 7 8 9 10 | return <tbody> {(() => { let row = [] for (var i = 0; i < numrows; i++) { row.push(<ObjectRow key={i} />) } return row })()} </tbody> |
好问题。
当我想添加一定数量的组件时,我所做的就是使用一个助手函数。
定义返回JSX的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 | const myExample = () => { let myArray = [] for(let i = 0; i<5;i++) { myArray.push(<MyComponent/>) } return myArray } //... in JSX <tbody> {myExample()} </tbody> |
你可以这样做:
1 2 | let foo = [1,undefined,3] { foo.map(e => !!e ? <Object /> : null )} |
即使这部密码也做同样的工作。
1 2 3 4 5 | <tbody> {array.map(i => <ObjectRow key={i.id} name={i.name} /> )} </tbody> |
下面的解决方案你可以在对象或平面阵列的迭代阵列的反馈中执行。
1 2 3 4 5 6 7 8 9 | const rows = []; const numrows = [{"id" : 01,"name" :"abc"}]; numrows.map((data, i) => { rows.push(<ObjectRow key={data.id} name={data.name}/>); }); <tbody> { rows } </tbody> |
黄金
ZZU1
更新:
即使我最近熟悉的对物体的一个编辑阵列的更好的方法,是直接在返回或不返回的情况下绘制地图。
返回图
1 2 3 4 5 6 | const numrows = [{"id" : 01,"name" :"abc"}]; <tbody> {numrows.map(data=> { return <ObjectRow key={data.id} name={data.name}/> })} </tbody> |
没有回复的地图
1 2 3 4 5 6 | const numrows = [{"id" : 01,"name" :"abc"}]; <tbody> {numrows.map(data=> ( <ObjectRow key={data.id} name={data.name}/> ))} </tbody> |
以下是来自React Doc的示例:https://facebook.github.io/react/docs/jsx-in-depth.html作为子级的javascript表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function Item(props) { return <li> {props.message} </li> ; } function TodoList() { const todos = ['finish doc', 'submit pr', 'nag dan to review']; return ( <ul> {todos.map((message) => <Item key={message} message={message} />)} </ul> ); } |
就你的情况而言,我建议这样写:
1 2 3 4 5 6 7 | function render() { return ( <tbody> {numrows.map((roe, index) => <ObjectRow key={index} />)} </tbody> ); } |
请注意,键非常重要,因为react使用键来区分数组中的数据。
问题是您没有返回任何JSX元素。对于这种情况还有其他解决方案,但我将提供最简单的解决方案:"使用映射函数"!
1 2 3 | <tbody> { numrows.map(item => <ObjectRow key={item.uniqueField} />) } </tbody> |
很简单很漂亮,不是吗?
你可以尝试新的环路
1 2 3 4 5 6 7 8 9 | const apple = { color: 'red', size: 'medium', weight: 12, sugar: 10 } for (const prop of apple.entries()){ console.log(prop); } |
HTTPS http://flaviocopes.com/react-how-to-loop/。
如果您没有密钥值,则打印阵列值,然后使用下一个密码-
1 {my_arr.map(item => {item} )}
如果numrow是一个数组,另一个答案是最好的方法是
1 2 3 4 5 | <tbody> { [...Array(numrows).fill(0)].map((value,index)=><ObjectRow key={index} />) } </tbody> |
您将要向数组中添加元素并呈现元素数组。这有助于减少重新呈现组件所需的时间。
下面是一些可能有帮助的粗略代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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>]) }) } } |
如果您真的想在JSX中使用for循环,可以使用IIFE。
1 2 3 4 5 6 7 8 9 10 11 | <tbody> { (function () { const view = []; for (let i = 0; i < numrows; i++) { view.push(<ObjectRow key={i}/>); } return view; }()) } </tbody> |
@如果我理解正确,您可以使用以下代码:
1 2 3 | <tbody> { new Array(numrows).fill(<ObjectRow/>) } </tbody> |
您可以使用此代码:
1 2 3 | <tbody> { new Array(numrows).fill('').map((item, ind) => <ObjectRow key={ind}/>) } </tbody> |
而这:
1 2 3 | <tbody> new Array(numrows).fill(ObjectRow).map((Item, ind) => <Item key={ind}/>) </tbody> |
好吧,给你。
1 2 3 4 5 | { [1, 2, 3, 4, 5, 6].map((value, index) => { return {value} }) } |
只需映射数组并返回您想要呈现的内容,不要忘记在返回元素中使用
我又找到了一个方法来跟踪地图伦德尔
1 | <tbody>{this.getcontent()}</tbody> |
和分离功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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元素是简单的JS,所以您可以遵循JavaScript的规则。所以您可以在javascript中使用这样的
1 2 3 4 5 | <tbody> for (var i=0; i < numrows; i++) { <ObjectRow/> } </tbody> |
但有效和最好的方法是使用
1 2 3 4 5 | <tbody> {listObject.map(function(listObject, i){ return <ObjectRow key={i} />; })} </tbody> |
在这里,有一件事是必要的:定义键。否则它会发出这样的警告:
warning.js:36 Warning: Each child in an array or iterator should have
a unique"key" prop. Check the render method ofComponentName . See
"link" for more information.
每当您需要将任何javascript代码放入JSX时,您应该将并将您的javascript代码放入这些括号中。就这么简单。
这样就可以在JSX/React中循环。
说:
1 2 3 | <tbody> {your piece of code in JavaScript } </tbody> |
例子:
1 2 3 | <tbody> { items.map( ( item ) > { console.log(item) }) } // items looping using map </tbody> |
JSX中的循环非常简单,尝试一下。
1 2 3 4 5 6 7 | { this.state.data.map((item,index)=>{ return( <ComponentName key={index} data={item}/> ); }) } |
在react中使用map是迭代数组的最佳实践。
为了防止ES6 synthax map出现某些错误,在react中使用如下方法:
1 2 3 | <tbody> {items.map((item, index) => <ObjectRow key={index} name={item.name} />)} </tbody> |
这里您调用一个组件,这样就不需要在箭头后面加括号。
但你也可以这样做:
1 2 3 | {items.map((item, index) => ( <ObjectRow key={index} name={item.name} /> ))} |
或:
1 2 3 4 5 6 | {items.map((item, index) => { // here you can log item return ( <ObjectRow key={index} name={item.name} /> ) })} |
我这么说是因为如果你在箭头后面加上一个括号"",反应将不会抛出错误并显示一个白名单。
1 2 3 4 5 6 7 8 9 10 11 | return ( <table> <tbody> { numrows.map((item, index) => { <ObjectRow data={item} key={index}> }) } </tbody> </table> ); |
1 2 3 4 5 | <tbody> numrows.map((row,index) => ( return <ObjectRow key={index}/> ) </tbody> |
在一个JSX块内,周围的Javascript将得到它,以便预先执行任何Javascript Action you are trying to do.
1 2 3 4 5 6 7 | <tr> <td> {data.map((item, index) => { {item} })} </td> </tr> |
这是Kinda浪潮,但你可以为任何阵列交换数据。这将为每个项目提供一张桌子和一张桌子项目。如果你在阵列中的每一个角落都有更多的东西
1 | <td>{item.someProperty}</td> |
在你想用不同的TD来处理的情况下,用不同的例子来处理。
在一个阵列和产生JSX元素的间隙中,有许多解决方案。所有的索引都很好,但所有的索引都直接在环路中使用。我们推荐使用数据的唯一标识作为一个关键字,但当我们没有从每一个对象在阵列中的唯一标识时,我们将使用索引作为一个关键词,但您不推荐使用索引作为一个关键词。
一个更重要的是,我们为什么要去地图,但为什么不去每一个,因为地图返回一个新的阵列。这些天有不同的行程图。
下面是不同版本的地图插图,详细说明如何使用唯一的键,以及如何使用映射来装载JSX元素。
MAP without return when returning single JSX element and unique id from data as a key version
1 2 3 4 5 | const {objects} = this.state; <tbody> {objects.map(object => <ObjectRow obj={object} key={object.id} />)} </tbody> |
MAP without return when returning multiple JSX elements and unique id from data as a key version
1 2 3 4 5 6 7 8 9 | const {objects} = this.state; <tbody> {objects.map(object => ( <ObjectRow obj={object} /> ))} </tbody> |
MAP without return when returning single JSX element and index as a key version
1 2 3 4 5 | const {objects} = this.state; <tbody> {objects.map((object, index) => <ObjectRow obj={object} key={`Key${index}`} />)} </tbody> |
MAP without return when returning multiple JSX elements and index as a key version
1 2 3 4 5 6 7 8 9 | const {objects} = this.state; <tbody> {objects.map((object, index) => ( <ObjectRow obj={object} /> ))} </tbody> |
MAP with return when returning multiple JSX elements and index as a key version
1 2 3 4 5 6 7 8 9 10 11 | const {objects} = this.state; <tbody> {objects.map((object, index) => { return ( <ObjectRow obj={object} /> ) })} </tbody> |
MAP with return when returning multiple JSX elements and unique id from data as a key version
1 2 3 4 5 6 7 8 9 10 11 | const {objects} = this.state; <tbody> {objects.map(object => { return ( <ObjectRow obj={object} /> ) })} </tbody> |
另一种方式是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | render(){ const {objects} = this.state; const objectItems = objects.map(object => { return ( <ObjectRow obj={object} /> ) }) return( <tbody> {objectItems} </tbody> ) } |
提供更直的前进解决方案,以方便您使用特定的流量计数以
1 2 3 4 5 6 7 8 | // Let's create typedArray with length of `numrows`-value const typedArray = new Int8Array(numrows); // typedArray.length is now 2 const rows = []; // Prepare rows-array for (let arrKey in typedArray) { // Iterate keys of typedArray rows.push(<ObjectRow key={arrKey} />); // Push to an rows-array } // Return rows return <tbody>{rows}</tbody>; |
你必须用JSX写
1 2 3 4 5 6 7 | <tbody> { objects.map((object, i) => ( <ObjectRow obj={object} key={i} /> )); } </tbody> |
- 关于javascript:for render in react渲染方法
- 关于reactjs:我如何使用for循环与反应?
- 如何在react本机应用程序的render函数中包含Javascript代码?
- 关于javascript:在JSX中使用For循环
- 关于javascript:如何在React中为JSX编写循环?
- 关于android:使用循环并渲染多个jsx项以后再返回渲染
- 关于javascript:如何创建一个包含1 ... N的数组
- 关于javascript:如何渲染重复的React元素?
- 如何循环或枚举JavaScript对象?
- 循环内的javascript闭包——简单的实践示例
- 如何使用对象作为成员循环一个普通的JavaScript对象?
- javascript中的数组循环
- 关于javascript:在React JSX中访问引号内的引号
- 关于javascript:React中的这三个点有什么作用?
- 关于reactjs:使用react路由器以编程方式导航
- 关于reactjs:有没有办法在React中访问父组件实例?
- 关于reactjs:在React应用程序中提供服务
- 关于javascript:为什么不将JSX保存为const渲染