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

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

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


当前回答

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

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

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

<tbody>
    {listObject.map(function(listObject, i){
        return <ObjectRow key={i} />;
    })}
</tbody>

在这里,有一件事是必要的:定义密钥。否则,它将发出如下警告:-

Warning.js:36警告:数组或迭代器中的每个子级都应该具有独特的“钥匙”道具。检查ComponentName的渲染方法。看见“链接”了解更多信息。

其他回答

我见过一个人/以前的答案在数组中使用.contat(),但不是这样。。。

我已经使用concat添加到字符串中,然后通过jQuery选择器在元素上呈现JSX内容:

let list = "<div><ul>";

for (let i=0; i<myArray.length; i++) {
    list = list.concat(`<li>${myArray[i].valueYouWant}</li>`);
}

list = list.concat("</ul></div>);

$("#myItem").html(list);

除非声明函数并用参数将其括起来,否则这是不可能的。在JSXExpression中,您只能编写表达式,而不能编写诸如for()、声明变量或类或if()语句之类的语句。

这就是为什么函数CallExpressions现在如此流行的原因。我的建议是:习惯它们。我会这样做:

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

过滤:

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

if():

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

如果-其他:

var names = getNames()
const people = {names && names.length ?
  <ul>{names.map(name => <li>{name}</li>)}</ul> : <p>no results</p> }
render() {
  const elements = ['one', 'two', 'three'];

  const items = []

  for (const [index, value] of elements.entries()) {
    items.push(<li key={index}>{value}</li>)
  }

  return (
    <div>
      {items}
    </div>
  )
}

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

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

它循环通过一组数据,为数据集中的每个项目创建一个新的React组件。这可以使用JavaScript的map()方法实现。

例如,如果您有一个称为“data”的对象数组和一个名为“ObjectRow”的React组件:

const rows = data.map((item, index) => <ObjectRow key={index} {...item} />);

然后,可以像这样渲染tbody标记中的行:

<tbody>{rows}</tbody>