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

Я пытаюсь преобразовать компонент jQuery в React.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');

Кажется, я не могу это получить, или что-то похожее на работу в компоненте JAX React.js. Вместо этого мне пришлось сделать следующее: сначала построим массив temp на нужную длину, а затем зациклируем массив.

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"
    ...
  );
}

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

Ответ 1

Обновлено: на момент реакции> 0,16

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

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


OLD:

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

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

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

Как говорят здесь документы

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

Ответ 2

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

Ответ 3

Я использую 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>
    );
}

Ответ 4

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

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

Ответ 5

Вот альтернативный синтаксис

Я очень часто использую этот фрагмент со списками, jsx и жирными стрелками:

return (
  {
    obj &&
      <ul className={styles.obj}>
        { Object.keys(obj).map((k, index) => <li key={index}>{ `${k}: ${obj[k]}` }</li>) }
      </ul>
  }
)

Ответ 6

Я думаю, что это самый простой способ прореагировать на JS

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