Как цикл и рендеринг элементов в React.js без массива объектов для отображения?

Я пытаюсь преобразовать компонент jQuery для реакции.js и одна из вещей, с которыми у меня возникают трудности, - это рендеринг n элементов на основе цикла for.

Я понимаю, что это невозможно или рекомендуется, и что там, где массив существует в модели, имеет смысл использовать 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. Вместо этого мне пришлось сделать следующее: сначала создать временный массив правильной длины, а затем зациклить матрица.

реагировать.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"
    ...
  );
}

конечно, это не может быть лучшим или единственным способом достичь этого? Что я упускаю?

5 ответов


обновлено: по состоянию на React > 0.16

метод Render не обязательно должен возвращать один элемент. Массив также может быть возвращен.

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>
));

документы здесь объясняют о детях JSX


старый:

вы можете использовать один цикл вместо

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>
);

вы также можете использовать .карта и фантазии ЕС6

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

кроме того, вы должны обернуть возвращаемое значение в контейнер. Я использовал div В приведенном выше примере

как говорят врачи здесь

В настоящее время в рендеринге компонента вы можете вернуть только один узел; если у вас есть, скажем, список divs для возврата, вы должны обернуть свои компоненты в div, span или любой другой компонент.


вот более функциональный пример с некоторыми функциями 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;

Я использую Object.keys(chars).map(...) для цикла в render

// 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>
    );
}

Array.from() принимает объект iterable для преобразования в массив и необязательную функцию map. Вы можете создать объект с помощью .length свойства следующим образом:

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

Я думаю, что это самый простой способ цикла в react JS

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