在React JSX中循环

Ben*_*rts 1131 javascript reactjs

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

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>
Run Code Online (Sandbox Code Playgroud)

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

Sop*_*ert 1082

可以想象它就像你只是调用JavaScript函数一样.你不能使用一个for函数调用参数的循环:

return tbody(
    for (var i = 0; i < numrows; i++) {
        ObjectRow()
    } 
)
Run Code Online (Sandbox Code Playgroud)

看看函数如何作为参数tbody传递for循环,当然这是一个语法错误.

但是你可以创建一个数组,然后将其作为参数传递:

var rows = [];
for (var i = 0; i < numrows; i++) {
    rows.push(ObjectRow());
}
return tbody(rows);
Run Code Online (Sandbox Code Playgroud)

使用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(<ObjectRow key={i} />);
}
return <tbody>{rows}</tbody>;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我的JavaScript示例几乎就是JSX转换的例子.使用Babel REPL来了解JSX的工作原理.

  • React需要有效地更新dom,在这种情况下,父级应该为每个孩子分配一个"key".参考:http://facebook.github.io/react/docs/multiple-components.html#dynamic-children (42认同)
  • 我可以保证最后一个例子仍然可以在最新的JSX编译器上正确编译. (8认同)
  • 这个示例将起作用,但它错过了一些重要的位,如`key`属性,以及在React代码库中没有真正使用的代码样式.请将此答案http://stackoverflow.com/questions/22876978/loop-inside-react-jsx/40326044#40326044视为正确答案. (7认同)
  • 这是可能的编译器已经改变,因为这个例子似乎并没有在[JSX编译器(http://facebook.github.io/react/jsx-compiler.html)编译,但是使用地图如下FakeRainBrigand的答案确实似乎正确编译. (3认同)
  • 这很好。FakeRainBrigand的答案适用于简单的数组迭代,但是对于不能使用map的场景(例如,变量中没有存储集合),此答案是必须的。 (3认同)

Bri*_*and 821

不确定这是否适用于您的情况,但通常地图是一个很好的答案.

如果这是你的代码与for循环:

<tbody>
    for (var i=0; i < objects.length; i++) {
        <ObjectRow obj={objects[i]} key={i}>
    } 
</tbody>
Run Code Online (Sandbox Code Playgroud)

你可以用map写这样的:

<tbody>
    {objects.map(function(object, i){
        return <ObjectRow obj={object} key={i} />;
    })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

ES6语法:

<tbody>
    {objects.map((object, i) => <ObjectRow obj={object} key={i} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)

  • 如果iteratee是一个数组,Map更有意义; 如果是循环,则for循环是合适的. (40认同)
  • `<tbody> {objects.map((o,i)=> <ObjectRow obj = {o} key = {i} />} </ tbody>`使用Reactify的ES6支持或Babel. (25认同)
  • 这很好,但是你不能映射一个对象..因为我会使用`for..in` (5认同)
  • 请记住,使用Object.keys时,键的顺序是任意的.我发现分别存储键的顺序效果很好,如果需要,还可以在对象字面上按顺序存储.这允许我编写像`this.props.order.map((k)=> <ObjectRow key = {k} {... this.props.items [k]} />)这样的代码. (4认同)
  • +1.我甚至使用ul(无序列表).`<ul> {objects.map((object:string,i:number)=> {return <li> {object} </ li>})} </ ul>`使用TypeScript (3认同)
  • 如果嵌套组件有删除事件,请勿使用索引作为键。 (3认同)

JMM*_*JMM 407

如果你还没有一个map()像@ FakeRainBrigand的答案那样的数组,并且想要内联这个,那么源布局对应的输出比@ SophieAlpert的答案更接近:

使用ES2015(ES6)语法(扩展和箭头功能)

http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview

<tbody>
  {[...Array(10)].map((x, i) =>
    <ObjectRow key={i} />
  )}
</tbody>
Run Code Online (Sandbox Code Playgroud)

回复:与Babel一起转发,其警告页面Array.from是传播所必需的,但目前(v5.8.23)在传播实际情况时似乎并非如此Array.我有一个文档问题,以澄清这一点.但请自担风险或使用polyfill.

香草ES5

Array.apply

<tbody>
  {Array.apply(0, Array(10)).map(function (x, i) {
    return <ObjectRow key={i} />;
  })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

内联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>
Run Code Online (Sandbox Code Playgroud)

结合其他答案的技术

保持源布局对应于输出,但使内联部分更紧凑:

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

使用ES2015语法和Array方法

有了Array.prototype.fill你能做到这一点,以替代使用作为传播上面所示:

<tbody>
  {Array(10).fill(1).map((el, i) =>
    <ObjectRow key={i} />
  )}
</tbody>
Run Code Online (Sandbox Code Playgroud)

(我认为你实际上可以省略任何参数fill(),但我不是100%.)感谢@FakeRainBrigand纠正我在早期版本的fill()解决方案中的错误(参见修订版).

key

在所有情况下,keyattr都会缓解开发构建的警告,但在子项中无法访问.如果您希望子项中的索引可用,则可以传递额外的attr.有关讨论,请参阅列表和密钥.

  • @corysimmons很酷,感谢`fill()`的信息.我现在记得我犹豫不决的原因是关于如何在ES规范中指出参数的可选性的问题(必须在某个时候查看).逗号只是一种消除数组元素的方法 - 在这种情况下是第一个.如果你希望索引来自你传播的数组的1..length而不是扩展数组的0..length-1,那么你可以这样做(因为省略的元素只对数组的长度有贡献而且不要t有相应的属性). (3认同)
  • 那“收益”呢?当我们有生成器时,将元素推入中间数组是很丑陋的。做他们的工作? (2认同)
  • @Mark我不知道生成器在这里真的适用。在JSX上下文中,此操作的关键是返回数组的表达式。因此,如果您打算以某种方式使用生成器,则无论如何都可能会对其进行扩展,并且它可能比此处基于ES2015的解决方案更为冗长。 (2认同)
  • [this](https://gist.github.com/mnpenner/2f852e9f2172844679f1)的详细程度如何?为什么JSX不接受任何可迭代的方法,而不仅仅是数组? (2认同)
  • @Mark确实比我使用的(ES5)IIFE示例更“冗长”,但比“ [... Array(x)]。map(()=&gt; &lt;El /&gt;)))更为冗长。版本,我认为这是最优雅的版本,以及为什么要使用它。回复:第二个问题,这很重要。似乎没有关于JSX的任何东西可以阻止它,所以它取决于React或转换后的JSX的另一个使用者对子级参数的处理方式,而我不看源代码就不能说。你知道吗?这是一个有趣的问题。 (2认同)
  • 请不要仅仅为了从 0..N 开始迭代而创建数组。那是 Javascript 的巅峰。 (2认同)

dan*_*ine 75

只需使用带有ES6语法的map Array方法:

<tbody>
  {items.map(item => <ObjectRow key={item.id} name={item.name} />)} 
</tbody>
Run Code Online (Sandbox Code Playgroud)

别忘了这家key酒店.


Ali*_*eza 73

使用数组映射函数是循环遍历元素数组并在React中根据它们创建组件的非常常见的方法,这是一个很好的方法来执行循环,这是在JSX中执行循环的非常有效和整洁的方式,它不是唯一的这样做的方法,但首选方式.

另外,不要忘记根据需要为每次迭代设置唯一的密钥.Map函数从0创建一个唯一索引,但不建议使用producd索引,但如果您的值是唯一的,或者如果有唯一键,则可以使用它们:

<tbody>
  {numrows.map(x=> <ObjectRow key={x.id} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)

如果您不熟悉Array上的map函数,那么来自MDN的行也很少:

map按顺序为数组中的每个元素调用一次提供的回调函数,并从结果中构造一个新数组.仅对已分配值的数组的索引(包括undefined)调用回调.它不会被调用缺少数组的元素(即,从未设置过的索引,已删除的索引或从未赋值的索引).

使用三个参数调用回调:元素的值,元素的索引和遍历的Array对象.

如果提供thisArg参数进行映射,则它将用作回调的此值.否则,undefined值将用作此值.回调最终可观察到的该值根据用于确定函数所见的通常规则来确定.

map不会改变调用它的数组(尽管回调,如果被调用,可能会这样做).


mpe*_*pen 47

如果您已经在使用lodash,则该_.times功能非常方便.

import React, { Component } from 'react';
import Select from './Select';
import _ from 'lodash';

export default class App extends Component {
    render() {
        return (
            <div className="container">
                <ol>
                    {_.times(3, i =>
                        <li key={i}>
                            <Select onSelect={this.onSelect}>
                                <option value="1">bacon</option>
                                <option value="2">cheez</option>
                            </Select>
                        </li>
                    )}
                </ol>
            </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @IsaiahGrey我认为它们只是被称为ES6 [方法定义](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions) (4认同)
  • 仅从 Lodash 导入 ```times```,而不是整个库。在开发过程中,随着 Lodash 发布更新,避免向后不兼容是可以的,但在生产中,导入整个库需要花费几秒钟的时间。 (2认同)

Bra*_*ong 38

您还可以在返回块之外提取:

render: function() {
    var rows = [];
    for (var i = 0; i < numrows; i++) {
        rows.push(<ObjectRow key={i}/>);
    } 

    return (<tbody>{rows}</tbody>);
}
Run Code Online (Sandbox Code Playgroud)


Eta*_*tai 26

我知道这是一个旧线程,但你可能想要检查http://wix.github.io/react-templates/,它允许你使用jsx风格的模板作为反应,使用一些指令(例如rt-重复).

您的示例,如果您使用react-templates,将是:

<tbody>
     <ObjectRow rt-repeat="obj in objects"/>
</tbody>
Run Code Online (Sandbox Code Playgroud)


Yan*_*Tay 23

有很多方法可以做到这一点.JSX最终被编译为JavaScript,所以只要你编写有效的JavaScript,你就会很好.

我的回答旨在巩固已经呈现的所有精彩方式:

如果没有对象数组,只需要行数:

return块内,创建Array和使用Array.prototype.map:

render() {
  return (
    <tbody>
      {Array(numrows).fill(null).map((value, index) => (
        <ObjectRow key={index}>
      ))}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

return块之外,只需使用普通的JavaScript for循环:

render() {
  let rows = [];
  for (let i = 0; i < numrows; i++) {
    rows.push(<ObjectRow key={i}/>);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

立即调用函数表达式:

render() {
  return (
    <tbody>
      {() => {
        let rows = [];
        for (let i = 0; i < numrows; i++) {
          rows.push(<ObjectRow key={i}/>);
        }
        return rows;
      }}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

如果你有一个对象数组

return块内,.map()每个对象到一个<ObjectRow>组件:

render() {
  return (
    <tbody>
      {objectRows.map((row, index) => (
        <ObjectRow key={index} data={row} />
      ))}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

return块之外,只需使用普通的JavaScript for循环:

render() {
  let rows = [];
  for (let i = 0; i < objectRows.length; i++) {
    rows.push(<ObjectRow key={i} data={objectRows[i]} />);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

立即调用函数表达式:

render() {
  return (
    <tbody>
      {(() => {
        const rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      })()}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

  • 好的答案:各种技术都只使用普通的javascript来显示javascript的功能,这要归功于其执行类似任务的各种方式。 (2认同)

小智 22

如果numrows是一个数组,那很简单.

<tbody>
   {numrows.map(item => <ObjectRow />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)

React中的数组数据类型非常好,数组可以支持新数组,并支持过滤,减少等.


小智 20

有几个答案指向使用该map声明.下面是一个完整的示例,它使用FeatureList组件中的迭代器,根据名为features的JSON数据结构列出Feature组件.

const FeatureList = ({ features, onClickFeature, onClickLikes }) => (
  <div className="feature-list">
    {features.map(feature =>
      <Feature
        key={feature.id}
        {...feature}
        onClickFeature={() => onClickFeature(feature.id)}
        onClickLikes={() => onClickLikes(feature.id)}
      />
    )}
  </div>
); 
Run Code Online (Sandbox Code Playgroud)

您可以在GitHub上查看完整的FeatureList代码.该功能夹具这里列出.


Jan*_*ang 16

让我们说你们州里有一系列物品:

[{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>
Run Code Online (Sandbox Code Playgroud)


Raf*_*fat 15

...或者您也可以准备一个对象数组并将其映射到一个函数以获得所需的输出.我更喜欢这个,因为它有助于我保持编码的良好实践,在渲染的返回中没有逻辑.

render() {
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>
  )
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*ell 15

只需使用.map()循环遍历您的集合并<ObjectRow>使用每次迭代的道具返回项目.

假设objects是某个阵列......

<tbody>
  { objects.map((obj, index) => <ObjectRow obj={ obj } key={ index }/> ) }
</tbody>
Run Code Online (Sandbox Code Playgroud)


Ali*_*aza 15

您可以在 React for循环中使用 .map()。

<tbody>
    { newArray.map(() => <ObjectRow />) }
</tbody>
Run Code Online (Sandbox Code Playgroud)


bha*_*waj 14

如果您选择这个转换内部回报率()渲染方法,最简单的办法是使用地图()方法.使用map()函数将数组映射到JSX语法,如下所示(使用ES6语法).


内部父组件:

key

请注意const { object } = this.props添加到子组件的属性.如果未提供键属性,则可以在控制台上看到以下警告.

警告:数组或迭代器中的每个子节点都应该具有唯一的"键"支柱.


现在,在ObjectRow组件中,您可以从其属性访问该对象.

在ObjectRow组件内部

const object = this.props.object

要么

object

这应该给你拿,你从父组件传递给变量对象keyObjectRow组件.现在,您可以根据您的目的吐出该对象中的值.


参考文献:

Javascript中的map()方法

ECMA Script 6或ES6


Dav*_*gan 14

ES2015/Babel的可能性是使用生成器函数来创建JSX数组:

function* jsxLoop(times, callback)
{
    for(var i = 0; i < times; ++i)
        yield callback(i);
}

...

<tbody>
    {[...jsxLoop(numrows, i =>
        <ObjectRow key={i}/>
    )]}
</tbody>
Run Code Online (Sandbox Code Playgroud)


J C*_*J C 14

我用这个:

gridItems = this.state.applications.map(app =>
          <ApplicationItem key={app.Id} app={app } />
);
Run Code Online (Sandbox Code Playgroud)

PD:永远不会忘记密钥,否则你会收到很多警告!


Ada*_*hue 13

我倾向于赞成编程逻辑发生在返回值之外的方法render.这有助于保持实际呈现的内容易于理解.

所以我可能会这样做:

import _ from 'lodash';

...

const TableBody = ({ objects }) => {
  const objectRows = objects.map(obj => <ObjectRow object={obj} />);      

  return <tbody>{objectRows}</tbody>;
} 
Run Code Online (Sandbox Code Playgroud)

不可否认,这是一个很少的代码,内联它可能工作正常.


Do *_*ync 13

ES2015 Array.from与map函数+ key

如果你什么都没有.map(),你可以使用Array.from()map重复元素:

<tbody>
  {Array.from({ length: 5 }, (value, key) => <ObjectRow key={key} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)


Jee*_*Mok 13

要循环的次数和回报,你可以的帮助下实现它frommap:

<tbody>
  {
    Array.from(Array(i)).map(() => <ObjectRow />)
  }
</tbody>
Run Code Online (Sandbox Code Playgroud)

哪里 i = number of times


小智 12

您的JSX代码将编译为纯JavaScript代码,任何标记都将被ReactElement对象替换.在JavaScript中,您无法多次调用函数来收集返回的变量.

它是非法的,唯一的方法是使用数组来存储返回变量的函数.

或者您可以使用自JavaScript ES5以来Array.prototype.map可用的处理这种情况.

也许我们可以编写其他编译器来重新创建一个新的JSX语法来实现像Angularng-repeat一样的重复函数.


Jur*_*emo 12

您当然可以使用.map解决,如其他答案所示.如果您已经使用了babel,您可以考虑使用jsx-control-statements 它们需要一些设置,但我认为它在可读性方面是值得的(特别是对于非反应开发人员).如果使用linter,还有eslint-plugin-jsx-control-statements


Dar*_*ega 12

如果您确实想要一个等效的for循环(您有一个数字,而不是数组),只需使用rangefrom Lodash

不要重新发明轮子,也不要混淆你的代码。只需使用标准实用程序库即可。

import range from 'lodash/range'

range(4);
// => [0, 1, 2, 3]

range(1, 5);
// => [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)


abh*_*006 11

这可以通过多种方式完成.

  1. 如上所述,在return存储数组中的所有元素之前
  2. 在里面循环 return

    方法1

     let container =[];
        let arr = [1,2,3] //can be anything array, object 
    
        arr.forEach((val,index)=>{
          container.push(<div key={index}>
                         val
                         </div>)
            /** 
            * 1. All loop generated elements require a key 
            * 2. only one parent element can be placed in Array
            * e.g. container.push(<div key={index}>
                                        val
                                  </div>
                                  <div>
                                  this will throw error
                                  </div>  
                                )
            **/   
        });
        return (
          <div>
             <div>any things goes here</div>
             <div>{container}</div>
          </div>
        )
    
    Run Code Online (Sandbox Code Playgroud)

    方法2

       return(
         <div>
         <div>any things goes here</div>
         <div>
            {(()=>{
              let container =[];
              let arr = [1,2,3] //can be anything array, object 
              arr.forEach((val,index)=>{
                container.push(<div key={index}>
                               val
                               </div>)
                             });
                        return container;     
            })()}
    
         </div>
      </div>
    )
    
    Run Code Online (Sandbox Code Playgroud)


Jav*_*rai 9

这是一个简单的解决方案.

var Object_rows=[];
for (var i=0; i < numrows; i++) {
    Object_rows.push(<ObjectRow/>)
} 
<tbody>
  {Object_rows}
</tbody>
Run Code Online (Sandbox Code Playgroud)

不需要映射和复杂的代码.您只需要将行推送到数组并返回值来呈现它.


Roh*_*dal 9

由于您在JSX代码中编写Javascript语法,因此需要将Javascript包装在花括号中.

row = () => {
   var rows = [];
   for (let i = 0; i<numrows; i++) {
       rows.push(<ObjectRow/>);
   }
   return rows;
}
<tbody>
{this.row()}  
</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 9

我喜欢它

<tbody>
  { numrows ? (
     numrows.map(obj => { return <ObjectRow /> }) 
    ) : null
  }
</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 9

这是React doc的示例:JavaScript表达式为子级

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

根据您的情况,我建议这样写:

function render() {
  return (
    <tbody>
      {numrows.map((roe, index) => <ObjectRow key={index} />)}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

请注意,密钥非常重要,因为React使用密钥来区分数组中的数据。


pop*_*ick 9

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

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

其中, n - 是您想要循环的次数。item将是未定义的,并且index会像往常一样。此外,ESLint不鼓励使用数组索引作为键。

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

为避免 item 为 undefined 带来的不便,您可以使用 an _,以便在 linting 时将其忽略并且不会抛出任何 linting 错误,例如

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


小智 8

好问题.

当我想添加一定数量的组件时,我所做的是使用辅助函数.

定义一个返回JSX的函数:

const myExample = () => {
    let myArray = []
    for(let i = 0; i<5;i++) {
        myArray.push(<MyComponent/>)
    }
    return myArray
}

//... in JSX

<tbody>
    {myExample()}
</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 8

您还可以使用自调用功能:

return <tbody>
           {(() => {
              let row = []
              for (var i = 0; i < numrows; i++) {
                  row.push(<ObjectRow key={i} />)
              }
              return row

           })()}
        </tbody>
Run Code Online (Sandbox Code Playgroud)


Hos*_*adi 8

Array.from是最好的方法。如果要创建具有一定长度的 JSX 数组。

function App() {
  return (
    <tbody>
      {Array.from({ length: 10 }, (_, key) => (
        <ObjectRow {...{ key }} />
      ))}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)

上面的例子是当你没有数组的时候,所以如果你有一个数组,你应该像这样在 JSX 中映射它:

function App() {
  return (
    <tbody>
      {list.map((item, key) => (
        <ObjectRow {...{ key }} />
      ))}
    </tbody>
  );
}
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以执行以下操作:

let foo = [1,undefined,3]
{ foo.map(e => !!e ? <Object /> : null )}
Run Code Online (Sandbox Code Playgroud)


Jan*_*ang 7

React 元素是简单的 JavaScript,因此您可以遵循 JavaScript 的规则。您可以for在 JavaScript 中使用循环,如下所示:-

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>
Run Code Online (Sandbox Code Playgroud)

但有效且最好的方法是使用该.map函数。如下图所示:-

<tbody>
    {listObject.map(function(listObject, i){
        return <ObjectRow key={i} />;
    })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

在这里,有一件事是必要的:定义密钥。否则它会抛出这样的警告:-

warning.js:36 警告:数组或迭代器中的每个子项都应该有一个唯一的“key”属性。检查 的渲染方法ComponentName。请参阅“链接”了解更多信息。


cha*_*mit 7

JSX 中的循环非常简单。尝试这个:

return this.state.data.map((item, index) => (
  <ComponentName key={index} data={item} />
));
Run Code Online (Sandbox Code Playgroud)


Hem*_*ari 7

以下是您可以在迭代对象数组或纯数组时做出的反应中可能的解决方案

const rows = [];
const numrows = [{"id" : 01, "name" : "abc"}];
numrows.map((data, i) => {
   rows.push(<ObjectRow key={data.id} name={data.name}/>);
});

<tbody>
    { rows }
</tbody>
Run Code Online (Sandbox Code Playgroud)

要么

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>
Run Code Online (Sandbox Code Playgroud)

更新:

我最近熟悉的迭代对象数组的更好方法是直接在渲染中使用.map进行返回或不返回

.map与返回

   const numrows = [{"id" : 01, "name" : "abc"}];
 <tbody>
       {numrows.map(data=> {
             return <ObjectRow key={data.id} name={data.name}/>
       })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

.map不返回

   const numrows = [{"id" : 01, "name" : "abc"}];
 <tbody>
       {numrows.map(data=> (
             <ObjectRow key={data.id} name={data.name}/>
       ))}
</tbody>
Run Code Online (Sandbox Code Playgroud)


Amr*_* LS 7

即使这段代码也可以完成相同的工作。

<tbody>
   {array.map(i => 
      <ObjectRow key={i.id} name={i.name} />
   )}
</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 7

使用地图功能。

<tbody> 
   {objects.map((object, i) =>  <ObjectRow obj={object} key={i} />)} 
</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以直接在 JSX 中执行相同的操作,使用 map 而不是 for-of 循​​环:

render: function() {
const items = ['one', 'two', 'three'];
 return (
  <ul>
     {items.map((value, index) => {
     return <li key={index}>{value}</li>
     })}
 </ul>
 )
}
Run Code Online (Sandbox Code Playgroud)


小智 7

只需做这样的事情:

<tbody>
    {new Array(numRows).fill("", 0, numRows).map((p, i) => <YourRaw key={i} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)


M S*_*que 6

好吧,你去。

{
 [1, 2, 3, 4, 5, 6].map((value, index) => {
  return <div key={index}>{value}</div>
 })
}
Run Code Online (Sandbox Code Playgroud)

所有您需要做的,只需映射数组并返回您要渲染的任何内容,请不要忘记key在return元素中使用。


Rev*_*n99 6

尝试这个

<tbody>
  {new Array(numrows).map((row,index)=><ObjectRow key={***someThingUniqe***}/>)} //don't use index as key 
</tbody>
Run Code Online (Sandbox Code Playgroud)

如果你想知道为什么你不应该在反应中使用索引作为键,请检查 这个


小智 5

return (
    <table>
       <tbody>
          {
            numrows.map((item, index) => {
              <ObjectRow data={item} key={index}>
            })
          }
       </tbody>
    </table>
);
Run Code Online (Sandbox Code Playgroud)


Gio*_*tos 5

如果您真的想在 JSX 中真正使用for循环,则可以使用IIFE

<tbody>
  {
    (function () {
      const view = [];
      for (let i = 0; i < numrows; i++) {
        view.push(<ObjectRow key={i}/>);
      }
      return view;
    }())
  }
</tbody>
Run Code Online (Sandbox Code Playgroud)


Bog*_*rai 5

@jacefarm如果我理解正确,则可以使用以下代码:

<tbody>
    { new Array(numrows).fill(<ObjectRow/>) } 
</tbody>
Run Code Online (Sandbox Code Playgroud)

您可以使用以下代码:

<tbody>
   { new Array(numrows).fill('').map((item, ind) => <ObjectRow key={ind}/>) } 
</tbody>
Run Code Online (Sandbox Code Playgroud)

和这个:

<tbody>
    new Array(numrows).fill(ObjectRow).map((Item, ind) => <Item key={ind}/>)
</tbody>
Run Code Online (Sandbox Code Playgroud)


Que*_*guy 5

在 React 中使用map是迭代数组的最佳实践。

为了防止ES6出现一些错误,React 中的语法映射如下所示:

<tbody>
    {items.map((item, index) => <ObjectRow key={index} name={item.name} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)

这里你调用一个组件,<ObjectRow/>,所以你不需要在箭头后面加上括号。

但你也可以这样做:

{items.map((item, index) => (
    <ObjectRow key={index} name={item.name} />
))}
Run Code Online (Sandbox Code Playgroud)

或者:

{items.map((item, index) => {
    // Here you can log 'item'
    return (
        <ObjectRow key={index} name={item.name} />
    )
})}
Run Code Online (Sandbox Code Playgroud)

我这么说是因为如果你在箭头后面放一个括号“{}”,React 不会抛出错误并且会显示白名单。


Ism*_*yev 5

问题是您没有返回任何 JSX 元素。对于这种情况还有另一种解决方案,但我将提供最简单的一种:“使用地图功能”!

<tbody>
  { numrows.map(item => <ObjectRow key={item.uniqueField} />) }
</tbody>
Run Code Online (Sandbox Code Playgroud)

就是这么简单又美丽,不是吗?


Amj*_*d K 5

每当您需要在JSX中放置任何JavaScript代码时,都应放置{},而不要在这些括号中放置JavaScript代码。就这么简单。

这样,您可以在jsx / react内部循环。

说:

<tbody>
    {your piece of code in JavaScript }
</tbody>
Run Code Online (Sandbox Code Playgroud)

例:

<tbody>
   { items.map((item) => {console.log(item)}) } // items looping using map
</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 5

我找到了另一种遵循地图渲染的解决方案:

 <tbody>{this.getcontent()}</tbody>
Run Code Online (Sandbox Code Playgroud)

还有一个单独的函数:

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;
}
Run Code Online (Sandbox Code Playgroud)

这个例子很容易解决很多问题。


小智 5

如果没有键值参数,则用于打印数组值,然后使用以下代码-

<div>
    {my_arr.map(item => <div>{item} </div> )}                    
</div>
Run Code Online (Sandbox Code Playgroud)


小智 5

在 JSX 块中使用{}JavaScript 代码,使其正确执行您尝试执行的任何 JavaScript 操作。

<tr>
  <td>
    {data.map((item, index) => {
      {item}
    })}
  </td>
</tr>
Run Code Online (Sandbox Code Playgroud)

这有点模糊,但您可以将数据交换为任何数组。这将为您提供每个项目的表格行和表格项目。如果数组的每个节点中只有一件事物,您将需要通过执行以下操作来专门针对该事物:

<td>{item.someProperty}</td>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您将需要用不同的内容包围它td并以不同的方式排列前面的示例。


Hem*_*ari 5

在迭代数组和生成 JSX 元素方面,已经发布了许多解决方案。它们都很好,但是它们都直接在循环中使用索引。我们建议使用数据中的唯一id作为键,但是当我们没有数组中每个对象的唯一id时,我们将使用索引作为键,但不建议直接使用索引作为键。

还有一件事为什么我们选择.map,但为什么不选择 .foEach 因为 .map 返回一个新数组。现在有不同的.map方法。

下面使用 .map 的不同版本详细说明了如何使用唯一键以及如何使用 .map 循环 JSX 元素。

当返回单个 JSX 元素和数据中的唯一 id 作为关键版本时,.map不返回:

const {objects} = this.state;

<tbody>
    {objects.map(object => <ObjectRow obj={object} key={object.id} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)

当返回多个 JSX 元素和数据中的唯一 id 作为关键版本时,.map不返回

const {objects} = this.state;

<tbody>
    {objects.map(object => (
        <div key={object.id}>
            <ObjectRow obj={object} />
        </div>
    ))}
</tbody>
Run Code Online (Sandbox Code Playgroud)

当返回单个 JSX 元素和索引作为键版本时,.map不返回:

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => <ObjectRow obj={object} key={`Key${index}`} />)}
</tbody>
Run Code Online (Sandbox Code Playgroud)

当返回多个 JSX 元素和索引作为键版本时,.map不返回:

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => (
        <div key={`Key${index}`}>
            <ObjectRow obj={object} />
        </div>
    ))}
</tbody>
Run Code Online (Sandbox Code Playgroud)

当返回多个 JSX 元素和索引作为键版本时带有 return 的.map :

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => {
        return (
            <div key={`Key${index}`}>
                <ObjectRow obj={object} />
            </div>
        )
    })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

当返回多个 JSX 元素和数据中的唯一 id 作为关键版本时,.map带有 return:

const {objects} = this.state;

<tbody>
    {objects.map(object => {
        return (
            <div key={object.id}>
                <ObjectRow obj={object} />
            </div>
        )
    })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

另一种方法是

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>
   )
}
Run Code Online (Sandbox Code Playgroud)


Jim*_*ala 5

如果您想要使用存储为 -value 的特定行计数,则提供更直接的解决方案Integer

在 的帮助下,typedArrays我们可以通过以下方式实现所需的解决方案。

// Let's create a 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>;
Run Code Online (Sandbox Code Playgroud)


Gil*_*cas 5

您可以尝试新的for循环

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

这里有几个例子


can*_*ero 5

除非您声明一个函数并用参数将其括起来,否则这是不可能的。在JSXExpression,你只能写表达式,不能写的语句如为(),声明变量或类,或if()语句。

这就是为什么函数 CallExpressions 如此受欢迎的原因。我的建议是:习惯它们。这就是我会做的:

const names = ['foo', 'bar', 'seba']
const people = <ul>{names.map(name => <li>{name}</li>)}</ul>
Run Code Online (Sandbox Code Playgroud)

过滤:

const names = ['foo', undefined, 'seba']
const people = <ul>{names.filter(person => !!person).map(name => <li>{name}</li>)}</ul>
Run Code Online (Sandbox Code Playgroud)

如果():

var names = getNames()
const people = {names && names.length &&
   <ul>{names.map(name => <li>{name}</li>)}</ul> }
Run Code Online (Sandbox Code Playgroud)

如果别的:

var names = getNames()
const people = {names && names.length ?
  <ul>{names.map(name => <li>{name}</li>)}</ul> : <p>no results</p> }
Run Code Online (Sandbox Code Playgroud)


Mse*_*Ali 5

您可以创建一个新组件,如下所示:

将密钥和数据传递给您的ObjectRow组件,如下所示:

export const ObjectRow = ({key,data}) => {
    return (
      <div>
          ...
      </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

创建一个新组件ObjectRowList以充当数据容器:

export const ObjectRowList = (objectRows) => {
    return (
      <tbody>
        {objectRows.map((row, index) => (
          <ObjectRow key={index} data={row} />
        ))}
      </tbody>
    );
}
Run Code Online (Sandbox Code Playgroud)


Var*_*nde 5

我不确定这是否适用于您的情况,但通常 [map][1] 是一个很好的答案。

如果这是您的for循环代码:

<tbody>
    for (var i=0; i < objects.length; i++) {
        <ObjectRow obj={objects[i]} key={i}>
    }
</tbody>
Run Code Online (Sandbox Code Playgroud)

你可以用map函数这样写:

<tbody>
    {objects.map(function(object, i){
        return <ObjectRow obj={object} key={i} />;
    })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

objects.map是循环objects.filter的最佳方式,也是过滤所需数据的最佳方式。过滤后的数据会形成一个新的数组,objects.some是检查数组是否满足给定条件(返回布尔值)的最佳方式。


kin*_*lex 5

您可以执行以下操作来重复组件numrows次数

<tbody>{Array(numrows).fill(<ObjectRow />)}</tbody>
Run Code Online (Sandbox Code Playgroud)


小智 5

这是我迄今为止在大多数项目中使用的:

const length = 5;
...
<tbody>
    {Array.from({ length }).map((_,i) => (
        <ObjectRow key={i}/>
    ))}
</tbody>
Run Code Online (Sandbox Code Playgroud)


Hac*_*gar 5

请尝试这个

<tbody>
   {Array.apply(0, Array(numrows)).map(function (x, i) {
     return <ObjectRow/>;
   })}
</tbody>
Run Code Online (Sandbox Code Playgroud)

或者

{[...Array(numrows)].map((x, i) =>
   <ObjectRow/>
)}
Run Code Online (Sandbox Code Playgroud)


小智 5

你可以在reactjs中使用.map() for循环

    <tbody>
        {items.map((value, index) => {
          return <li key={index}>{value}</li>
        })}
      </tbody>
)
Run Code Online (Sandbox Code Playgroud)


lin*_*ing 5

一行(假设 numrows 是一个数字):

<tbody>
  {
    Array(numrows).fill().map(function (v, i) {
      return <ObjectRow/>
    })
  }
</tbody>
Run Code Online (Sandbox Code Playgroud)