Як циклічно та візуалізувати елементи в 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.