如何在没有要映射的对象数组的情况下循环和渲染 React.js 中的元素?

How to loop and render elements in React.js without an array of objects to map?

我正在尝试将 jQuery 组件转换为 React.js,我遇到的困难之一是基于 for 循环渲染 n 个元素。

我知道这是不可能的,也不推荐这样做,而且在模型中存在数组的情况下,使用 map 是完全有意义的。很好,但是如果没有数组怎么办?相反,你有等于给定数量的要渲染的元素的数值,那么你应该怎么做?

这是我的示例,我想根据元素的层次结构为元素添加任意数量的 span 标记作为前缀。所以在第 3 级,我想要在文本元素之前有 3 个 span 标签。

在javascript中:

for (var i = 0; i < level; i++) {
    $el.append('<span class="indent"></span>');
}
$el.append('Some text value');

我似乎无法理解这个,或者任何类似于在 JSX React.js 组件中工作的东西。相反,我必须执行以下操作,首先将临时数组构建为正确的长度,然后循环该数组。

React.js

render: function() {
  var tmp = [];
  for (var i = 0; i < this.props.level; i++) {
    tmp.push(i);
  }
  var indents = tmp.map(function (i) {
    return (
      <span className='indent'></span>
    );
  });

  return (
    ...
    {indents}
    "Some text value"
    ...
  );
}

这肯定不是最好的方法,或者是唯一的方法?我错过了什么?

更新:截至 React > 0.16

Render 方法不一定要return 单个元素。数组也可以 returned.

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return indents;

return this.props.level.map((item, index) => (
    <span className="indent" key={index}>
        {index}
    </span>
));

Docs here explaining about JSX children


旧:

您可以改用一个循环

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return (
   <div>
    {indents}
    "Some text value"
   </div>
);

你也可以使用.map和fancy es6

return (
   <div>
    {this.props.level.map((item, index) => (
       <span className='indent' key={index} />
    ))}
    "Some text value"
   </div>
);

此外,您必须将 return 值包装在容器中。我在上面的例子中使用了div

正如文档所说 here

Currently, in a component's render, you can only return one node; if you have, say, a list of divs to return, you must wrap your components within a div, span or any other component.

我正在使用 Object.keys(chars).map(...) 在渲染中循环

// chars = {a:true, b:false, ..., z:false}

render() {
    return (
       <div>
        {chars && Object.keys(chars).map(function(char, idx) {
            return <span key={idx}>{char}</span>;
        }.bind(this))}
        "Some text value"
       </div>
    );
}

这里有一些 ES6 特性的更实用的例子:

'use strict';

const React = require('react');

function renderArticles(articles) {
    if (articles.length > 0) {      
        return articles.map((article, index) => (
            <Article key={index} article={article} />
        ));
    }
    else return [];
}

const Article = ({article}) => {
    return ( 
        <article key={article.id}>
            <a href={article.link}>{article.title}</a>
            <p>{article.description}</p>
        </article>
    );
};

const Articles = React.createClass({
    render() {
        const articles = renderArticles(this.props.articles);

        return (
            <section>
                { articles }
            </section>
        );
    }
});

module.exports = Articles;

我认为这是在 React js 中循环的最简单方法

<ul>
    {yourarray.map((item)=><li>{item}</li>)}
</ul>

Array.from() 将一个可迭代对象转换为数组和一个可选的映射函数。您可以创建一个带有 .length 属性 的对象,如下所示:

return Array.from({length: this.props.level}, (item, index) => 
  <span className="indent" key={index}></span>
);

如果你负担得起创建一个临时数组,你仍然可以使用map

{
    new Array(this.props.level).fill(0).map((_, index) => (
        <span className='indent' key={index}></span>
    ))
}

这是可行的,因为 new Array(n).fill(x) 创建了一个大小为 n 的数组,其中填充了 x,然后可以帮助 map