Ako vytvoriť slučku a vykresliť prvky v React.js bez poľa objektov na mapovanie?

Snažím sa previesť komponent jQuery do React.js a jednou z vecí, s ktorými mám problémy, je vykresľovanie n počtu prvkov na základe cyklu for.

Chápem, že to nie je možné ani odporúčané a že tam, kde v modeli existuje pole, má zmysel použiť mapu. To je v poriadku, ale čo keď pole nemáte? Namiesto toho máte číselnú hodnotu, ktorá sa rovná danému počtu prvkov na vykreslenie, čo potom máte urobiť?

Tu je môj príklad, chcem prefixovať prvok ľubovoľným počtom značiek span na základe jeho hierarchickej úrovne. Takže na úrovni 3 chcem 3 značky span pred textovým prvkom.

V javascripte:

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

Zdá sa mi, že nemôžem dosiahnuť, aby toto alebo niečo podobné fungovalo v komponente JSX React.js. Namiesto toho som musel urobiť nasledovné, najprv vytvoriť dočasné pole na správnu dĺžku a potom toto pole zacykliť.

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

Určite to nemôže'byť najlepší alebo jediný spôsob, ako to dosiahnuť? Čo mi uniká?

Riešenie

Aktualizované: Od verzie React > 0.16

Metóda Render nemusí nevyhnutne vracať jeden prvok. Môže sa vrátiť aj pole.

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

ALEBO

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

Dokumenty tu vysvetľujú o deťoch JSX


OLD:

Namiesto toho môžete použiť jednu slučku

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

Môžete tiež použiť .map a vymyslieť es6

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

Taktiež musíte návratovú hodnotu zabaliť do kontajnera. Vo vyššie uvedenom príklade som použil div

Ako sa uvádza v dokumentácii tu

V súčasnosti môžete vo vykresľovaní komponentu'vrátiť len jeden uzol; ak máte napríklad zoznam divov, ktoré chcete vrátiť, musíte komponenty zabaliť do div, span alebo iného komponentu.

Komentáre (9)

Tu je funkčnejší príklad s niektorými funkciami 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;
Komentáre (5)

Používam Object.keys(chars).map(...) na vytvorenie slučky pri vykresľovaní

// 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>
    );
}
Komentáre (2)