it-roy-ru.com

Цикл внутри React JSX

Я пытаюсь сделать что-то вроде следующего в React JSX (где ObjectRow является отдельным компонентом):

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

Я понимаю и понимаю, почему это JSX недопустимо, поскольку JSX соответствует вызовам функций. Однако, исходя из шаблона земли и будучи новичком в JSX, я не уверен, как бы я достиг вышеуказанного (добавление компонента несколько раз).

996
Ben Roberts

Думайте об этом, как будто вы просто вызываете функции JavaScript. Вы не можете использовать цикл for, куда будут идти аргументы вызова функции:

return tbody(
    for (var i = 0; i < numrows; i++) {
        ObjectRow()
    } 
)

Посмотрите, как функции tbody передается цикл for в качестве аргумента, и, конечно, это синтаксическая ошибка.

Но вы можете создать массив и передать его в качестве аргумента:

var rows = [];
for (var i = 0; i < numrows; i++) {
    rows.Push(ObjectRow());
}
return tbody(rows);

Вы можете использовать в основном ту же структуру при работе с JSX:

var rows = [];
for (var i = 0; i < numrows; i++) {
    // note: we add a key prop here to allow react to uniquely identify each
    // element in this array. see: https://reactjs.org/docs/lists-and-keys.html
    rows.Push(<ObjectRow key={i} />);
}
return <tbody>{rows}</tbody>;

Между прочим, мой пример JavaScript почти точно то, во что превращается этот пример JSX. Поиграйте с Babel REPL , чтобы понять, как работает JSX.

906
Sophie Alpert

Не уверен, что это подойдет для вашей ситуации, но часто map - хороший ответ.

Если это был ваш код с циклом for:

<tbody>
    for (var i=0; i < objects.length; i++) {
        <ObjectRow obj={objects[i]} key={i}>
    } 
</tbody>

Вы можете написать это так с помощью map :

<tbody>
    {objects.map(function(object, i){
        return <ObjectRow obj={object} key={i} />;
    })}
</tbody>

Синтаксис ES6:

<tbody>
    {objects.map((object, i) => <ObjectRow obj={object} key={i} />)}
</tbody>
726
FakeRainBrigand

Если у вас еще нет массива для map(), такого как ответ @ FakeRainBrigand, и вы хотите встроить его, чтобы компоновка источника соответствовала выводу, более близкому, чем ответ @ SophieAlpert:

С синтаксисом ES2015 (ES6) (функции разворота и стрелок)

http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview

<tbody>
  {[...Array(10)].map((x, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

Re: транспарант с Babel, его страница предупреждений говорит, что для распространения требуется Array.from, но в настоящее время (v5.8.23) это не так при распространении фактической Array. У меня есть проблема с документацией открыта, чтобы уточнить это. Но используйте на свой страх и риск или polyfill.

Ваниль ES5

Array.apply

<tbody>
  {Array.apply(0, Array(10)).map(function (x, i) {
    return <ObjectRow key={i} />;
  })}
</tbody>

Встроенный IIFE

http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview

<tbody>
  {(function (rows, i, len) {
    while (++i <= len) {
      rows.Push(<ObjectRow key={i} />)
    }
    return rows;
  })([], 0, 10)}
</tbody>

Сочетание техник из других ответов

Держите исходный макет, соответствующий выходу, но сделайте встроенную часть более компактной:

render: function () {
  var rows = [], i = 0, len = 10;
  while (++i <= len) rows.Push(i);

  return (
    <tbody>
      {rows.map(function (i) {
        return <ObjectRow key={i} index={i} />;
      })}
    </tbody>
  );
}

С синтаксисом ES2015 и методами Array

С Array.prototype.fill вы можете сделать это в качестве альтернативы использованию распространения, как показано выше:

<tbody>
  {Array(10).fill(1).map((el, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

(Я думаю, что вы могли бы фактически опустить любой аргумент для fill(), но я не на 100% об этом.) Спасибо @FakeRainBrigand за исправление моей ошибки в более ранней версии решения fill() (см. Ревизии).

key

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

358
JMM

Просто используя метод map Array с синтаксисом ES6:

<tbody>
  {items.map(item => <ObjectRow key={item.id} name={item.name} />)} 
</tbody>

Не забудьте свойство key.

61
danielfeelfine

Использование Array map function является очень распространенным способом прохождения Array элементов и создания компонентов в соответствии с ними в React , это отличный способ сделать цикл, который довольно эффективен и аккуратен способ сделать ваши циклы вJSX, это не единственный способ сделать это, но предпочтительный способ.  

Также не забывайте иметь уникальный ключ для каждой итерации, как требуется. Функция карты создает уникальный индекс из 0, но не рекомендуется использовать индекс producd, но если ваше значение уникально или если есть уникальный ключ, вы можете использовать их:

<tbody>
  {numrows.map(x=> <ObjectRow key={x.id} />)}
</tbody>

Также несколько строк изMDN, если вы не знакомы с функцией карты в массиве:

map вызывает предоставленную функцию обратного вызова один раз для каждого элемента в массив, по порядку, и создает новый массив из результатов. Перезвоните вызывается только для индексов массива, которым присвоены значения, в том числе неопределенный. Он не вызывается для отсутствующих элементов массив (то есть индексы, которые никогда не были установлены, которые были удалены или которым никогда не присваивалось значение).

обратный вызов вызывается с тремя аргументами: значение элемента, индекс элемента и объекта Array, по которому осуществляется обход.

Если для сопоставления указан параметр thisArg, он будет использоваться как обратный вызов это значение. В противном случае значение undefined будет использоваться как это его значение. Это значение, в конечном итоге наблюдаемое обратным вызовом, равно определяется в соответствии с обычными правилами для определения этого видел по функции.

map не изменяет массив, в котором он вызывается (хотя callback, если вызван, может сделать это).

58
Alireza

Если вы уже используете lodash, функция _.times удобна.

import React, { Component } from 'react';
import Select from './Select';
import _ from 'lodash';

export default class App extends Component {
    render() {
        return (
            <div className="container">
                <ol>
                    {_.times(3, i =>
                        <li key={i}>
                            <Select onSelect={this.onSelect}>
                                <option value="1">bacon</option>
                                <option value="2">cheez</option>
                            </Select>
                        </li>
                    )}
                </ol>
            </div>
        );
    }
}
36
mpen

Вы также можете извлечь вне блока возврата:

render: function() {
    var rows = [];
    for (var i = 0; i < numrows; i++) {
        rows.Push(<ObjectRow key={i}/>);
    } 

    return (<tbody>{rows}</tbody>);
}
28
Brandon Sibeitokgong

Я знаю, что это старый поток, но вы можете проверить http://wix.github.io/react-templates/ , который позволяет вам использовать шаблоны в стиле jsx в реакции с несколькими директивами ( такой как rt-repeat).

Ваш пример, если бы вы использовали ответные шаблоны, был бы:

<tbody>
     <ObjectRow rt-repeat="obj in objects"/>
</tbody>
21
Etai

если numrows - это массив, и это очень просто.

<tbody>
   {numrows.map(item => <ObjectRow />)}
</tbody>

Тип данных массива в React намного лучше, массив может поддерживать новый массив и поддерживать фильтрацию, уменьшение и т.д.

17
lulin

Есть несколько ответов, указывающих на использование оператора map. Вот полный пример использования итератора в компоненте FeatureList для перечисления компонентов Feature на основе структуры данных JSON, называемой features.

const FeatureList = ({ features, onClickFeature, onClickLikes }) => (
  <div className="feature-list">
    {features.map(feature =>
      <Feature
        key={feature.id}
        {...feature}
        onClickFeature={() => onClickFeature(feature.id)}
        onClickLikes={() => onClickLikes(feature.id)}
      />
    )}
  </div>
); 

Вы можете просмотреть полный текст { FeatureList code на GitHub. Список функций приведен здесь .

16
Manav Sehgal

скажем, у нас есть массив элементов в вашем состоянии:

[{name: "item1", id: 1}, {name: "item2", id: 2}, {name: "item3", id: 3}]

<tbody>
    {this.state.items.map((item) => {
        <ObjectRow key={item.id} name={item.name} />
    })} 
</tbody>
12
Jan Franz Palngipang

... Или вы также можете подготовить массив объектов и сопоставить его с функцией, чтобы получить желаемый результат. Я предпочитаю это, потому что это помогает мне поддерживать хорошую практику кодирования без логики в возвращении рендера. 

render() {
const mapItem = [];
for(let i =0;i<item.length;i++) 
  mapItem.Push(i);
const singleItem => (item, index) {
 // item the single item in the array 
 // the index of the item in the array
 // can implement any logic here
 return (
  <ObjectRow/>
)

}
  return(
   <tbody>{mapItem.map(singleItem)}</tbody>
  )
}
12
Rafi Ud Daula Refat

Просто используйте .map(), чтобы пройтись по своей коллекции и возвращать элементы <ObjectRow> с реквизитом из каждой итерации.

Предполагая, что objects массив где-то ...

<tbody>
  { objects.map((obj, index) => <ObjectRow obj={ obj } key={ index }/> ) }
</tbody>
11
Joshua Michael Calafell

Если вы решите преобразовать это внутри return () метода render, самым простым вариантом будет использование метода map (). Сопоставьте ваш массив с синтаксисом JSX с помощью функции map (), как показано ниже (используется синтаксис ES6).


Внутри родительского компонента:

<tbody> { objectArray.map((object, index) => <ObjectRow key={index} object={object}>) } </tbody>

Обратите внимание, что атрибут key добавлен в ваш дочерний компонент. Если вы не указали ключевой атрибут, вы можете увидеть следующее предупреждение на своей консоли.

Предупреждение: каждый дочерний элемент в массиве или итераторе должен иметь уникальная «ключевая» опора.


Теперь в компоненте ObjectRow вы можете получить доступ к объекту из его свойств.

Внутри компонента ObjectRow

const { object } = this.props

или же 

const object = this.props.object

Это должно получить вам объект, который вы передали из родительского компонента в переменную object в компоненте ObjectRow. Теперь вы можете выплевывать значения в этом объекте в соответствии с вашей целью.


Рекомендации : 

метод map () в Javascript

ECMA Script 6 или ES6

11
bharadhwaj

Возможность ES2015/Babel - использовать функцию генератора для создания массива JSX:

function* jsxLoop(times, callback)
{
    for(var i = 0; i < times; ++i)
        yield callback(i);
}

...

<tbody>
    {[...jsxLoop(numrows, i =>
        <ObjectRow key={i}/>
    )]}
</tbody>
11
David Q Hogan

Я использую это:

gridItems = this.state.applications.map(app =>
                            <ApplicationItem key={app.Id} app={app } />
                            );

PD: никогда не забывайте ключ, иначе у вас будет много предупреждений!

11
J C

Есть несколько способов сделать это. JSX в конечном итоге компилируется в JavaScript, поэтому, пока вы пишете правильный JavaScript, вы будете в порядке.

Мой ответ нацелен на объединение всех чудесных способов, уже представленных здесь:

Если у вас нет массива объектов, просто количество строк:

внутри блока return, создавая Array и используя Array.prototype.map:

render() {
  return (
    <tbody>
      {Array(numrows).fill(null).map((value, index) => (
        <ObjectRow key={index}>
      ))}
    </tbody>
  );
}

вне блока return, просто используйте обычный цикл for JavaScript:

render() {
  let rows = [];
  for (let i = 0; i < numrows; i++) {
    rows.Push(<ObjectRow key={i}/>);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}

немедленно вызывается выражение функции:

render() {
  return (
    <tbody>
      {() => {
        let rows = [];
        for (let i = 0; i < numrows; i++) {
          rows.Push(<ObjectRow key={i}/>);
        }
        return rows;
      }}
    </tbody>
  );
}

Если у вас есть массив объектов

в блоке return.map() каждый объект компонента <ObjectRow>:

render() {
  return (
    <tbody>
      {objectRows.map((row, index) => (
        <ObjectRow key={index} data={row} />
      ))}
    </tbody>
  );
}

вне блока return, просто используйте обычный цикл for JavaScript:

render() {
  let rows = [];
  for (let i = 0; i < objectRows.length; i++) {
    rows.Push(<ObjectRow key={i} data={objectRows[i]} />);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}

немедленно вызывается выражение функции:

render() {
  return (
    <tbody>
      {(() => {
        let rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.Push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      })()}
    </tbody>
  );
}
10
Yangshun Tay

Я склоняюсь к подходу, в котором логика программирования происходит за пределами возвращаемого значения render. Это помогает сохранить то, что на самом деле легко сделать.

Так что я бы, наверное, сделал что-то вроде:

import _ from 'lodash';

...

const TableBody = ({ objects }) => {
  const objectRows = objects.map(obj => <ObjectRow object={obj} />);      

  return <tbody>{objectRows}</tbody>;
} 

По общему признанию, это такой небольшой объем кода, что его вставка может работать нормально.

9
Adam Donahue

ES2015 Array.from с функцией карты + клавиша

Если у вас нет ничего для .map(), вы можете использовать Array.from() с mapFn для повторения элементов:

<tbody>
  {Array.from({ length: 5 }, (v, k) => <ObjectRow key={k} />)}
</tbody>
9
Do Async

Ваш JSX-код будет скомпилирован в чистый код JavaScript, любые теги будут заменены объектами ReactElement. В JavaScript вы не можете вызывать функцию несколько раз, чтобы собрать возвращаемые переменные.

Это недопустимо, единственный способ - использовать массив для хранения возвращаемых функцией переменных.

Или вы можете использовать Array.prototype.map который доступен начиная с JavaScript ES5 , чтобы справиться с этой ситуацией.

Возможно, мы сможем написать другой компилятор, чтобы воссоздать новый синтаксис JSX для реализации функции повтора, такой же как Angular's ng-repeat .

9
hlissnake

вы, конечно, можете решить с помощью .map, как подсказывает другой ответ. Если вы уже используете babel, вы можете подумать об использовании jsx-control-операторов Они требуют небольшой настройки, но я думаю, что это стоит с точки зрения читабельности (особенно для нереагирующего разработчика) .Если вы используете линтер, есть также eslint-plugin-jsx-control-Statement

9
Jurgo Boemo

Чтобы выполнить цикл несколько раз и вернуться, вы можете достичь его с помощью from и map :

  <tbody>
    {
      Array.from(Array(i)).map(() => <ObjectRow />)
    }
  </tbody>

где i = number of times

8
Jee Mok

Это можно сделать несколькими способами.

  1. Как указано выше, перед return сохраните все элементы в массиве
  2. Цикл внутри return

    Способ 1

     let container =[];
        let arr = [1,2,3] //can be anything array, object 
    
        arr.forEach((val,index)=>{
          container.Push(<div key={index}>
                         val
                         </div>)
            /** 
            * 1. All loop generated elements require a key 
            * 2. only one parent element can be placed in Array
            * e.g. container.Push(<div key={index}>
                                        val
                                  </div>
                                  <div>
                                  this will throw error
                                  </div>  
                                )
            **/   
        });
        return (
          <div>
             <div>any things goes here</div>
             <div>{container}</div>
          </div>
        )
    

    Способ 2 

       return(
         <div>
         <div>any things goes here</div>
         <div>
            {(()=>{
              let container =[];
              let arr = [1,2,3] //can be anything array, object 
              arr.forEach((val,index)=>{
                container.Push(<div key={index}>
                               val
                               </div>)
                             });
                        return container;     
            })()}
    
         </div>
      </div>
    )
    
8
abhirathore2006

Я использую это как

<tbody>
{ numrows ? (
   numrows.map(obj => { return <ObjectRow /> }) 
) : null}
</tbody>
7
Sampath

Поскольку вы пишете синтаксис Javascript внутри JSX-кода, вам нужно заключить Javascript в фигурные скобки.

row = () => {
   var rows = [];
   for (let i = 0; i<numrows; i++) {
       rows.Push(<ObjectRow/>);
   }
   return rows;
}
<tbody>
{this.row()}  
</tbody>
6
Rohit Jindal

Вы также можете использовать функцию самовызвания: 

return <tbody>
           {(() => {
              let row = []
              for (var i = 0; i < numrows; i++) {
                  row.Push(<ObjectRow key={i} />)
              }
              return row

           })()}
        </tbody>
5
Fba Shad

Отличный вопрос.

Когда я хочу добавить определенное количество компонентов, я использую вспомогательную функцию.

Определите функцию, которая возвращает JSX:

const myExample = () => {
    let myArray = []
    for(let i = 0; i<5;i++) {
        myArray.Push(<MyComponent/>)
    }
    return myArray
}

//... in JSX

<tbody>
    {myExample()}
</tbody>
5
Christophe Pouliot

Вот простое решение для этого.

var Object_rows=[];
for (var i=0; i < numrows; i++) {
    Object_rows.Push(<ObjectRow/>)
} 
<tbody>
{Object_rows}
</tbody>

Нет необходимости в отображении и сложном коде. Вам просто нужно вставить строки в массив и вернуть значения для его визуализации.

5
Javasamurai

Вы можете сделать что-то вроде:

let foo = [1,undefined,3]
{ foo.map(e => !!e ? <Object /> : null )}
4

Даже этот кусок кода делает ту же работу.

    <tbody>
      {array.map(i => 
        <ObjectRow key={i.id} name={i.name} />
      )}
    </tbody>
4
Amruth LS

Вот пример из документа React: https://facebook.github.io/react/docs/jsx-in-depth.html#javascript-expressions-as-children

function Item(props) {
  return <li>{props.message}</li>;
}

function TodoList() {
  const todos = ['finish doc', 'submit pr', 'nag dan to review'];
  return (
    <ul>
      {todos.map((message) => <Item key={message} message={message} />)}
    </ul>
  );
}

в вашем случае я предлагаю написать так:

function render() {
  return (
    <tbody>
      {numrows.map((roe, index) => <ObjectRow key={index} />)}
    </tbody>
  );
}

Обратите внимание, что ключ очень важен, потому что React использует ключ для различения данных в массиве.

4
Sinka Lee

ниже приведены возможные решения, которые вы можете сделать в промежутках между повторением массива объектов или простого массива.

const rows = [];
const numrows = [{"id" : 01, "name" : "abc"}];
numrows.map((data, i) => {
   rows.Push(<ObjectRow key={data.id} name={data.name}/>);
});

<tbody>
    { rows }
</tbody>

OR

const rows = [];
const numrows = [1,2,3,4,5];
for(let i=1, i <= numrows.length; i++){
   rows.Push(<ObjectRow key={numrows[i]} />);
};

<tbody>
    { rows }
</tbody>

Обновление:

еще более лучший подход, который я знаю в последние дни для итерации массива объектов - это .map непосредственно в рендере с возвратом или без возврата 

.map с возвратом

   const numrows = [{"id" : 01, "name" : "abc"}];
 <tbody>
       {numrows.map(data=> {
             return <ObjectRow key={data.id} name={data.name}/>
       })}
</tbody>

.map без возврата

   const numrows = [{"id" : 01, "name" : "abc"}];
 <tbody>
       {numrows.map(data=> (
             <ObjectRow key={data.id} name={data.name}/>
       ))}
</tbody>
4
Hemadri Dasari

Ну, вот и все.

{
 [1, 2, 3, 4, 5, 6].map((value, index) => {
  return <div key={index}>{value}</div>
 })
}

Все, что вам нужно сделать, просто отобразить ваш массив и вернуть то, что вы хотите визуализировать, и, пожалуйста, не забудьте использовать key в возвращаемом элементе.

3
M Shafique

Проблема в том, что вы не возвращаете jsx-элемент. Для таких случаев есть и другие решения, но я приведу самое простое: «используйте функцию карты»!

<tbody>
  { numrows.map(item => <ObjectRow key={item.uniqueField} />) }
</tbody>

Это так просто и красиво, не правда ли?

3
Ismayil Niftaliyev

для печати значения массива, если у вас нет пары ключ-значение, используйте следующий код: 

  <div>
       {my_arr.map(item => <div>{item} </div> )}                    
  </div>
3
Som

Вы можете использовать IIFE, если вы действительно хотите буквально использовать цикл for внутри JSX.

<tbody>
  {
    (function () {
      const view = [];
      for (let i = 0; i < numrows; i++) {
        view.Push(<ObjectRow key={i}/>);
      }
      return view;
    }())
  }
</tbody>
3
Giovanni Lobitos

@jacefarm Если я правильно понял, вы можете использовать этот код:

<tbody>
    { new Array(numrows).fill(<ObjectRow/>) } 
</tbody>

Либо вы можете использовать этот код:

<tbody>
   { new Array(numrows).fill('').map((item, ind) => <ObjectRow key={ind}/>) } 
</tbody>

И это:

<tbody>
    new Array(numrows).fill(ObjectRow).map((Item, ind) => <Item key={ind}/>)
</tbody>
3
Bogdan Surai

Вы хотите добавить элементы в массив и визуализировать массив элементов.
Это может помочь сократить время, необходимое для повторной визуализации компонента.

Вот примерный код, который может помочь:

MyClass extends Component {
    constructor() {
        super(props)
        this.state = { elements: [] }
    }
    render() {
        return (<tbody>{this.state.elements}<tbody>)
    }
    add() {
        /*
         * The line below is a cheap way of adding to an array in the state.
         * 1) Add <tr> to this.state.elements
         * 2) Trigger a lifecycle update.
         */
        this.setState({
            elements: this.state.elements.concat([<tr key={elements.length}><td>Element</td></tr>])
        })
    }
}
3
Shawn Khameneh
return (
        <table>
          <tbody>
          {
            numrows.map((item, index) => {
              <ObjectRow data={item} key={index}>
            })
          }
          </tbody>
        </table>
      );
2
anshu purohit

Использование карты в реакции - это лучшие практики для итерации по массиву. 

Чтобы предотвратить некоторые ошибки с es6, синтаксическая карта используется следующим образом: 

<tbody>
 {items.map((item, index) => <ObjectRow key={index} name={item.name} />)} 
</tbody>

Здесь вы вызываете Компонент, поэтому вам не нужно ставить скобки после стрелки.

Но вы можете сделать это тоже: 

{items.map((item, index) => (
<ObjectRow key={index} name={item.name} />
))}

или же : 

{items.map((item, index) => {
// here you can log item 
      return (
       <ObjectRow key={index} name={item.name} />
     )
})}

Я говорю это потому, что если вы поставите скобку "{}" после стрелки, реакция не выдаст ошибку и отобразит белый список.

2
Quentin Malguy

Если numrows - это массив, в то время как другие ответы лучше всего использовать метод map. Если его нет и вы получаете к нему доступ только из jsx, вы также можете использовать этот метод ES6: 

<tbody>
    { 
      [...Array(numrows).fill(0)].map((value,index)=><ObjectRow key={index} />)
    } 
</tbody>
2
Kamuran Sönecek

Я нашел еще одно решение, чтобы следовать карте Render 

 <tbody>{this.getcontent()}</tbody>

И отдельная функция 

 getcontent() {
const bodyarea = this.state.movies.map(movies => (
  <tr key={movies._id}>
    <td>{movies.title}</td>
    <td>{movies.genre.name}</td>
    <td>{movies.numberInStock}</td>
    <td>{movies.publishDate}</td>
    <td>
      <button
        onClick={this.deletMovie.bind(this, movies._id)}
        className="btn btn-danger"
      >
        Delete
      </button>
    </td>
  </tr>
));
return bodyarea;
}

этот пример легко решает многие проблемы

2
Saad Mirza
<tbody>
   numrows.map((row,index) => (
      return <ObjectRow key={index}/>
   )
</tbody>
2
vimal ram

Всякий раз, когда вам нужно поместить какой-либо код JavaScript в ваш JSX, вы должны поместить {}, а затем поместить свой код JavaScript в эти скобки…. Просто так просто.  

Таким образом, вы можете зацикливаться внутри jsx/реагировать.

Сказать:

   <tbody>
    {your piece of code in JavaScript }
  </tbody>

Пример:

   <tbody>
    { items.map( ( item ) > { console.log(item) }) } // items looping using map
  </tbody>
2
Must Keem J

цикл внутри JSX очень просто попробуйте это.

 {
      this.state.data.map((item,index)=>{
        return(
           <ComponentName key={index} data={item}/>
        );
      })
    }
2
chauhan amit

Элементы React - это простые JS, поэтому вы можете следовать правилу javascript. Таким образом, вы можете использовать цикл for в JavaScript следующим образом:

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

Но правильный и лучший способ - использовать функцию .map. Показано ниже:-

<tbody>
    {listObject.map(function(listObject, i){
        return <ObjectRow key={i} />;
    })}
</tbody>

Здесь необходимо одно: определить ключ. В противном случае он выдаст предупреждение:

warning.js: 36 Предупреждение. У каждого дочернего элемента в массиве или итераторе должен быть уникальная «ключевая» опора. Проверьте метод рендеринга ComponentName. Увидеть "ссылка" для получения дополнительной информации.

2
Jani Devang

используйте {} вокруг javascript внутри блока JSX, чтобы заставить его правильно выполнять любое действие javascript, которое вы пытаетесь выполнить. 

<tr>
  <td>
    {data.map((item, index) => {
      {item}
    })}
  </td>
</tr>

Это довольно расплывчато, но вы можете поменять данные для любого массива. Это даст вам строку таблицы и элемент таблицы для каждого элемента. Если у вас есть более чем одна вещь в каждом узле массива, вы захотите нацелиться на это конкретно, выполнив что-то вроде этого:

<td>{item.someProperty}</td>

В этом случае вы захотите окружить его другим тд и расположить предыдущий пример по-другому.

1
esewalson

Если вы не объявите функцию и не заключите ее в параметры, это невозможно. В JSXExpression вы можете писать только EXPRESSIONS и не можете писать STATEMENTS, такие как for (), объявлять переменные или классы или оператор if ().

Вот почему функция CallExpressions сегодня так настроена. Мой совет, привыкни к ним. Вот что я бы сделал:

const names = ['foo', 'bar', 'seba']
const people = <ul>{names.map(name => <li>{name}</li>)}</ul>

фильтрация:

const names = ['foo', undefined, 'seba']
const people = <ul>{names.filter(person => !!person).map(name => <li>{name}</li>)}</ul>

если():

var names = getNames()
const people = {names && names.length && 
   <ul>{names.map(name => <li>{name}</li>)}</ul> }

если еще:

var names = getNames()
const people = {names && names.length ? 
  <ul>{names.map(name => <li>{name}</li>)}</ul> : <p>no results</p> }

Надеюсь, поможет

1
cancerbero

Вы должны написать в JSX 

<tbody>
    { 
    objects.map((object, i) => (
        <ObjectRow obj={object} key={i} />
    ));
    }
</tbody>
1
sultan aslam

Существует много решений, касающихся перебора массива и создания элементов jsx. Все они хороши, но все они используют индекс непосредственно в цикле. Мы рекомендуем использовать уникальный идентификатор из данных в качестве ключа, но когда у нас нет уникального идентификатора для каждого объекта в массиве, мы будем использовать индекс в качестве ключа, но вам не рекомендуется использовать индекс в качестве ключа напрямую.

Еще одна вещь, почему мы обращаемся к .map, но почему бы не .foEach, потому что .map возвращает новый массив. Есть разные способы сделать .map в эти дни. 

Ниже другая версия использования .map подробно иллюстрирует, как использовать уникальный ключ и как использовать .map для зацикливания элементов jsx.

.map без возврата при возврате отдельного элемента jsx и уникального идентификатора из данных в качестве ключевой версии

const {objects} = this.state;

<tbody>
    {objects.map(object => <ObjectRow obj={object} key={object.id} />)}
</tbody>

.map без возврата при возврате нескольких элементов jsx и уникального идентификатора из данных в качестве ключевой версии

const {objects} = this.state;

<tbody>
    {objects.map(object => (
       <div key={object.id}>
          <ObjectRow obj={object} />
       </div>
    ))}
</tbody>

.map без возврата при возврате отдельного элемента jsx и индекса в качестве ключевой версии

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => <ObjectRow obj={object} key={`Key${index}`} />)}
</tbody>

.map без возврата при возврате нескольких jsx-элементов и индекса в качестве ключевой версии

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => (
       <div key={`Key${index}`}>
          <ObjectRow obj={object} />
       </div>
    ))}
</tbody>

.map с возвратом при возврате нескольких элементов jsx и индексом в качестве ключевой версии

const {objects} = this.state;

<tbody>
    {objects.map((object, index) => {
       return (
         <div key={`Key${index}`}>
            <ObjectRow obj={object} />
         </div>
       )
    })}
</tbody>

.map с возвратом при возврате нескольких элементов jsx и уникального идентификатора из данных в качестве ключевой версии

const {objects} = this.state;

<tbody>
    {objects.map(object => {
       return (
         <div key={object.id}>
            <ObjectRow obj={object} />
         </div>
       )
    })}
</tbody>

Другой способ 

render(){
  const {objects} = this.state;
  const objectItems = objects.map(object => {
       return (
         <div key={object.id}>
            <ObjectRow obj={object} />
         </div>
       )
    })
return(
   <div>
     <tbody>
       {objectItems}
     </tbody>
   </div>
 )
}
1
Hemadri Dasari

Чтобы обеспечить более простое решение в случае, если вы хотите использовать конкретное количество строк, которое хранится как значение Integer-. С помощью typedArrays мы смогли достичь желаемого решения следующим образом.

// Let's create typedArray with length of `numrows`-value
const typedArray = new Int8Array(numrows); // typedArray.length is now 2
const rows = []; // Prepare rows-array
for (let arrKey in typedArray) { // Iterate keys of typedArray
  rows.Push(<ObjectRow key={arrKey} />); // Push to an rows-array
}
// Return rows
return <tbody>{rows}</tbody>; 
0
Jimi Pajala

Вы можете попробовать новый цикл 

const Apple = {
   color: 'red',
   size: 'medium',
   weight: 12,
   sugar: 10
}
for (const prop of Apple.entries()){
   console.log(prop);
}

Вот несколько примеров: https://flaviocopes.com/react-how-to-loop/

0
Bert lucas