Як циклічно та візуалізувати елементи в React.js без масиву об’єктів для відображення?


145

Я намагаюся перетворити компонент jQuery в React.js, і однією з речей, з якими я зіткнувся, є надання n кількості елементів на основі циклу for.

Я розумію, що це неможливо або не рекомендується, і там, де в моделі існує масив, це має повний сенс використовувати map. Це добре, але що робити, коли у вас немає масиву? Натомість у вас є числове значення, яке прирівнюється до заданої кількості елементів для візуалізації, то що робити?

Ось мій приклад, я хочу встановити префікс елемента з довільною кількістю проміжок тегів на основі його ієрархічного рівня. Отже, на рівні 3 я хочу 3 тегів прольоту перед текстовим елементом.

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

Звичайно, це не може бути найкращим чи єдиним способом цього досягти? Що я пропускаю?



також ви могли просто зробити це: jsfiddle.net/crl/69z2wepo/19804
caub

Відповіді:


241

Оновлено: Станом на Реакція> 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


СТАРИЙ:

Ви можете використовувати один цикл замість цього

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 та фантастичні es6

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

Також вам потрібно загортати повернене значення в контейнер. Я використовував div у наведеному вище прикладі

Як кажуть тут документи

На даний момент у візуалізації компонента ви можете повернути лише один вузол; якщо у вас є, скажімо, список div-файлів для повернення, ви повинні загортати свої компоненти в div, span або будь-який інший компонент.


1
Це працює, і це набагато простіше спасибі. Так, я знаю, що вам потрібно загортати повернене значення в контейнер, я це роблю, це вже просто відсутнє в прикладі.
Джонатан Майлз

2
додайте ключі всередині циклу. ключі важливі для реакції.
Аамір Афріді

4
Я шукав тебе все своє життя
olleh

2
@ElgsQianChen Це неможливо. Його треба обгорнути якоюсь міткою. Якщо {indents} повертає один елемент
кузова

2
Я не розумію, чому в цій відповіді згадується метод карти, оскільки він працює лише для об'єктів Array, про що явно йдеться в запитанні, це не так.
flukyspore

47

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

1
Це виглядає як найреактивніший спосіб зробити це. Передайте значення в якості реквізиту іншому підкомпоненту. Дякую!
Майкл Джованні Пумо

Це чудово! Ідеально підходить, коли ваш рендер () важкий html.
matthew

Щоб зробити його більше ES6, ви можете використовувати import React from "react"іexport default Articles
jonlink

1
Ця відповідь навіть не намагається відповісти на питання. Питання було зрозумілим, як перетворити for loopмасив у масив (або об'єкт) на карті, щоб вивести n кількість елементів у компонент React, не маючи масив елементів. Ви рішення повністю ігнорує цей факт і передбачає, що вам передається масив статей від реквізиту.
Джонатан Майлз

17

Я використовую 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>
    );
}

Ваша відповідь працювала на мене, але лише після того, як я додав chars && ...і .bind(this)після закінчення своєї функції. Мені цікаво, чому просто Object...(і так далі) не працювало. Я продовжував визначатися.
m00saca

2
Це не відповідає на запитання, воно спеціально говорить без масиву об’єктів для розбору, а пояснення прямо говорить про те, що я хочу перетворити цикл for для відображення для відображення в компонент React. Ви замінили масив для об'єкта, який не допомагає відповісти на питання, або додаєте додаткове значення.
Джонатан Майлз

16

Array.from()приймає ітерабельний об'єкт для перетворення в масив та необов'язкові функції карти. Ви можете створити об'єкт із .lengthвластивістю таким чином:

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

Я просто випадково побачив ваше запитання після прослуховування цього минулого тижня, тому це було найшвидшим способом застосувати те, що я дізнався! syntax.fm/show/043/…
conradj

1
Просто те, що мені було потрібно для надання X кількості елементів, дякую!
Ліран Н

0

Я думаю, що це найпростіший спосіб зафіксувати реакцію на js

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

2
Це не відповідає на запитання, будь ласка, прочитайте його повністю, перш ніж намагатися відповісти.
Джонатан Майлз

це допомогло мені і заощадити час.
Аджай Малхотра
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.