web-dev-qa-db-fra.com

Boucle à l'intérieur de React JSX

J'essaie de faire quelque chose comme ceci dans React JSX (où ObjectRow est un composant séparé):

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

Je comprends et comprends pourquoi JSX n’est pas valide, car JSX mappe des appels de fonction. Cependant, venant de pays modèles et étant nouveau dans JSX, je ne suis pas sûr de la façon dont je réaliserais ce qui précède (en ajoutant un composant plusieurs fois).

892
Ben Roberts

Pensez-y comme si vous appeliez simplement des fonctions JavaScript. Vous ne pouvez pas utiliser une boucle for où les arguments d'un appel de fonction iraient:

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

Voyez comment la fonction tbody reçoit une boucle for en tant qu'argument, ce qui est bien sûr une erreur de syntaxe.

Mais vous pouvez créer un tableau, puis le transmettre sous forme d'argument:

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

Vous pouvez utiliser essentiellement la même structure lorsque vous travaillez avec 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>;

Incidemment, mon exemple JavaScript correspond presque exactement à ce que cet exemple de JSX transforme. Jouez avec Babel REPL pour avoir une idée du fonctionnement de JSX.

906
Sophie Alpert

Vous ne savez pas si cela fonctionnera dans votre situation, mais souvent map est une bonne réponse.

S'il s'agissait de votre code avec la boucle for:

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

Vous pourriez l'écrire comme ceci avec map :

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

Syntaxe ES6:

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

Si vous n'avez pas déjà de tableau à map() comme la réponse de @ FakeRainBrigand et que vous souhaitez le mettre en ligne afin que la présentation source corresponde à la sortie plus proche de celle de @ SophieAlpert:

Avec la syntaxe ES2015 (ES6) (fonctions d'étalement et de flèche)

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

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

Re: transpiler avec Babel, sa page caveats indique que Array.from est requis pour la propagation, mais pour le moment (v5.8.23), cela ne semble pas être le cas lors de la propagation d'une réelle Array. J'ai un problème de documentation ouvert pour clarifier cela. Mais utilisez à vos risques et périls ou polyfill.

Vanilla ES5

Array.apply

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

Inline 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>

Combinaison de techniques d'autres réponses

Conservez la mise en page source correspondant à la sortie, mais rendez la partie en ligne plus compacte:

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

Avec la syntaxe ES2015 et les méthodes Array

Avec Array.prototype.fill, vous pourriez utiliser cette option plutôt que d'utiliser spread comme illustré ci-dessus:

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

(Je pense que vous pouvez en fait omettre tout argument relatif à fill(), mais je ne suis pas à 100% à ce sujet.) Merci à @FakeRainBrigand pour avoir corrigé mon erreur dans une version antérieure de la solution fill() (voir les révisions).

key

Dans tous les cas, key attr atténue un avertissement lors de la construction du développement, mais n'est pas accessible dans l'enfant. Vous pouvez transmettre un attr supplémentaire si vous souhaitez que l'index soit disponible dans l'enfant. Voir Listes et touches pour discussion.

358
JMM

En utilisant simplement la méthode map Array avec la syntaxe ES6:

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

N'oubliez pas la propriété key.

61
danielfeelfine

Utiliser la fonction Array map est un moyen très courant de parcourir un Array d'éléments et de créer des composants en fonction de ceux-ci dans React. C'est un excellent moyen de créer une boucle assez efficace et ordonnée. façon de faire vos boucles dans JSX, c’est pas la seule façon de le faire, mais la manière préférée . 

De plus, n'oubliez pas de disposer d'une clé unique pour chaque itération, selon vos besoins. La fonction Map crée un index unique à partir de 0, mais il n'est pas recommandé d'utiliser l'index producd, mais si votre valeur est unique ou s'il existe une clé unique, vous pouvez les utiliser:

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

Aussi quelques lignes de MDN si vous ne connaissez pas la fonction map sur Array:

map appelle une fonction de rappel fournie une fois pour chaque élément d'un fichier tableau, dans l’ordre, et construit un nouveau tableau à partir des résultats. rappeler est appelé uniquement pour les index du tableau auxquels des valeurs ont été assignées, y compris indéfini. Il n'est pas appelé pour les éléments manquants du array (c’est-à-dire des index qui n’ont jamais été définis, qui ont été supprimés ou qui n’ont jamais reçu de valeur).

callback est appelé avec trois arguments: la valeur de l'élément, l'index de l'élément et l'objet Array en cours de parcours.

Si un paramètre thisArg est fourni pour mapper, il sera utilisé comme callback est cette valeur. Sinon, la valeur indéfinie sera utilisée comme c'est cette valeur. Cette valeur finalement observable par le rappel est déterminé selon les règles habituelles pour la détermination du ce vu par une fonction.

map ne mute pas le tableau sur lequel il est appelé (bien que callback, s'il est appelé, puisse le faire).

58
Alireza

Si vous utilisez déjà lodash, la fonction _.times est pratique.

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

Vous pouvez également extraire en dehors du bloc de retour:

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

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

Je sais que c’est un vieux fil de discussion, mais vous voudrez peut-être utiliser http://wix.github.io/react-templates/ , qui vous permet d’utiliser des modèles de style jsx pour réagir, avec quelques directives ( comme rt-repeat).

Votre exemple, si vous utilisiez react-templates, serait:

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

si numrows est un tableau, c'est très simple.

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

Le type de données de tableau dans React est très meilleur, tableau peut sauvegarder un nouveau tableau et prendre en charge le filtrage, la réduction, etc.

17
lulin

Plusieurs réponses suggèrent d'utiliser l'instruction map. Voici un exemple complet d'utilisation d'un itérateur dans le composant FeatureList pour répertorier les composants Feature en fonction d'une structure de données JSON appelée 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>
); 

Vous pouvez voir le code complet FeatureList sur GitHub. Le luminaire features est listé ici .

16
Manav Sehgal

disons que nous avons un tableau d'objets dans votre état:

[{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

... ou vous pouvez également préparer un tableau d'objets et le mapper à une fonction pour obtenir le résultat souhaité. Je préfère cela, car cela m'aide à maintenir la bonne pratique de codage sans logique dans le rendu du rendu. 

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

Utilisez simplement .map() pour parcourir votre collection et renvoyer des éléments <ObjectRow> avec des accessoires de chaque itération.

En supposant que objects est un tableau quelque part ...

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

Si vous optez pour la conversion dans la méthode return () de render, l'option la plus simple consiste à utiliser la méthode map () Mappez votre tableau dans la syntaxe JSX en utilisant la fonction map (), comme indiqué ci-dessous (la syntaxe ES6 est utilisée).


Composant parent interne:

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

Veuillez noter l'attribut key ajouté à votre composant enfant. Si vous n'avez pas fourni d'attribut de clé, vous pouvez voir l'avertissement suivant sur votre console.

Avertissement: chaque enfant d'un tableau ou d'un itérateur doit avoir un unique "clé" prop.


Maintenant, au composant ObjectRow, vous pouvez accéder à l'objet à partir de ses propriétés.

Composant Inside ObjectRow

const { object } = this.props

ou 

const object = this.props.object

Cela devrait vous chercher l'objet que vous avez passé du composant parent à la variable object dans le composant ObjectRow. Vous pouvez maintenant cracher les valeurs de cet objet en fonction de votre objectif.


Références : 

Méthode map () en Javascript

ECMA Script 6 ou ES6

11
bharadhwaj

Une possibilité ES2015/Babel utilise une fonction de générateur pour créer un tableau de 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

J'utilise ceci:

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

PD: ne jamais oublier la clé ou vous aurez beaucoup d'avertissements!

11
J C

Il y a plusieurs façons de s'y prendre. JSX est finalement compilé en JavaScript, donc tant que vous écrivez en JavaScript valide, vous serez bon.

Ma réponse vise à consolider toutes les merveilleuses façons déjà présentées ici:

Si vous n'avez pas de tableau d'objets, indiquez simplement le nombre de lignes:

dans le bloc return, en créant une Array et en utilisant Array.prototype.map:

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

en dehors du bloc return, utilisez simplement un code JavaScript normal pour la boucle:

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

expression de fonction immédiatement appelée:

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

Si vous avez un tableau d'objets

dans le bloc return, .map() chaque objet en un composant <ObjectRow>:

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

en dehors du bloc return, utilisez simplement un code JavaScript normal pour la boucle:

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

expression de fonction immédiatement appelée:

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

J'ai tendance à privilégier une approche dans laquelle la logique de programmation se situe en dehors de la valeur de retour de render. Cela aide à garder ce qui est réellement rendu facile à maîtriser.

Donc, je ferais probablement quelque chose comme:

import _ from 'lodash';

...

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

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

Certes, il s’agit d’une si petite quantité de code qu’il pourrait fonctionner correctement.

9
Adam Donahue

ES2015 Array.from avec la fonction de carte + touche

Si vous n'avez rien à .map(), vous pouvez utiliser Array.from() avec la variable mapFn pour répéter des éléments:

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

Votre code JSX sera compilé en code JavaScript pur, toutes les balises seront remplacées par des objets ReactElement. En JavaScript, vous ne pouvez pas appeler une fonction plusieurs fois pour collecter les variables renvoyées.

C'est illégal, le seul moyen est d'utiliser un tableau pour stocker les variables retournées par la fonction.

Ou vous pouvez utiliser Array.prototype.map qui est disponible depuis JavaScript ES5 pour gérer cette situation.

Peut-être pourrions-nous écrire un autre compilateur pour recréer une nouvelle syntaxe JSX afin d'implémenter une fonction de répétition, tout comme Angular's ng-repeat .

9
hlissnake

vous pouvez bien sûr résoudre avec une .map comme suggéré par l'autre réponse. Si vous utilisez déjà babel, vous pourriez penser à utiliser jsx-control-statement Ils nécessitent un peu de réglage, mais je pense que cela vaut la peine en termes de lisibilité (surtout pour les développeurs non réactifs) ..__ Si vous utilisez un linter, il y a aussi eslint-plugin-jsx-control-statement

9
Jurgo Boemo

Pour effectuer une boucle plusieurs fois et revenir, vous pouvez y parvenir à l'aide de from et map :

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

i = number of times

8
Jee Mok

Cela peut être fait de plusieurs façons.

  1. Comme suggéré ci-dessus, avant return, enregistrez tous les éléments du tableau
  2. Boucle à l'intérieur return

    Méthode 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>
        )
    

    Méthode 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

Je l'utilise comme

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

Puisque vous écrivez la syntaxe Javascript dans le code JSX, vous devez envelopper votre Javascript dans des accolades.

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

Vous pouvez également utiliser une fonction auto-invoquante: 

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

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

Excellente question.

Ce que je fais lorsque je veux ajouter un certain nombre de composants est d'utiliser une fonction d'assistance.

Définissez une fonction qui renvoie 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

Voici une solution simple à cela.

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

Aucun mappage et code complexe requis.

5
Javasamurai

Vous pouvez faire quelque chose comme:

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

Même ce morceau de code fait le même travail.

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

Voici un exemple de doc 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>
  );
}

comme votre cas, je suggère d'écrire comme ceci:

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

Veuillez noter que la clé est très importante car React utilise la clé pour différer les données d'un tableau.

4
Sinka Lee

vous trouverez ci-dessous des solutions possibles que vous pouvez appliquer en réagissant entre un tableau d’itérations ou un tableau simple.

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>

Mettre à jour:

encore mieux, je connais les derniers jours pour itérer un tableau d’objets: .map directement dans le rendu avec ou sans retour 

.map avec retour

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

.map sans retour

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

Eh bien, voilà.

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

Tout ce que vous avez à faire, il vous suffit de mapper votre tableau et de renvoyer ce que vous voulez restituer. N'oubliez pas d'utiliser key dans l'élément return.

3
M Shafique

Le problème est que vous ne renvoyez aucun élément jsx. Il existe une autre solution pour de tels cas, mais je vais vous fournir la plus simple: "utiliser la fonction de carte"!

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

C'est si simple et beau, n'est-ce pas?

3

pour imprimer la valeur du tableau si vous n'avez pas la paire clé/valeur, utilisez le code ci-dessous - 

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

Vous pouvez utiliser un IIFE si vous voulez réellement utiliser littéralement une boucle dans JSX.

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

@jacefarm Si je comprends bien, vous pouvez utiliser ce code:

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

Soit vous pouvez utiliser ce code:

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

Et ça:

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

Vous voudrez ajouter des éléments à un tableau et rendre le tableau des éléments.
Cela peut aider à réduire le temps requis pour restituer le composant.

Voici un code approximatif qui pourrait aider:

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

L'utilisation de map dans react constitue une bonne pratique pour effectuer une itération sur un tableau. 

Pour éviter certaines erreurs avec es6 synthax map est utilisé comme ceci dans react: 

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

Ici, vous appelez un composant, vous n'avez donc pas besoin de mettre des parenthèses après la flèche.

Mais vous pouvez faire cela aussi: 

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

ou : 

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

Je dis cela parce que si vous mettez un crochet "{}" après que la flèche réagisse ne jettera pas d'erreur et affichera une liste blanche.

2
Quentin Malguy

Si numrows est un tableau car l'autre répond, le meilleur moyen est la méthode map. Si ce n'est pas le cas et que vous y accédez uniquement à partir de jsx, vous pouvez également utiliser cette méthode ES6: 

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

J'ai trouvé une solution supplémentaire pour suivre la carte Render 

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

Et fonction séparée 

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

cet exemple résout facilement de nombreux problèmes

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

Chaque fois que vous devez insérer du code JavaScript dans votre JSX, vous devez placer {} et placer votre code JavaScript entre ces crochets . C'est aussi simple que cela.  

De cette façon, vous pourrez faire une boucle dans jsx/react.

Dire:

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

Exemple:

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

boucle dans jsx est très simple essayez ceci.

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

Les éléments de réaction sont de simples JS, vous pouvez donc suivre la règle du javascript. Donc, vous pouvez utiliser une boucle for en javascript comme ceci: -

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

Mais le meilleur moyen consiste à utiliser la fonction .map. Indiqué ci-dessous:-

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

Ici, une chose est nécessaire: définir la clé. Sinon, un avertissement comme celui-ci sera lancé: -

warning.js: 36 Avertissement: chaque enfant d'un tableau ou d'un itérateur doit avoir un unique "clé" prop. Vérifiez la méthode de rendu de ComponentName. Voir "lien" pour plus d'informations.

2
Jani Devang
render() {
  const elements = ['one', 'two', 'three'];

  const items = []

  for (const [index, value] of elements.entries()) {
    items.Push(<li key={index}>{value}</li>)
  }

  return (
    <div>
      {items}
    </div>
  )
}
1
Pacific P. Regmi

utilisez {} autour de javascript dans un bloc JSX pour que celui-ci exécute correctement l'action javascript que vous tentez de réaliser. 

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

C'est un peu vague, mais vous pouvez échanger des données pour n’importe quel tableau. Cela vous donnera une ligne de table et un élément de table pour chaque élément. Si vous avez plus d'une seule chose dans chaque nœud du tableau, vous voudrez cibler cela spécifiquement en faisant quelque chose comme ceci:

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

Dans ce cas, vous voudrez l'entourer d'un td différent et organiser l'exemple précédent différemment.

1
esewalson

Sauf si vous déclarez une fonction et que vous la mettez entre paramètres, ce n’est pas possible. Dans une expression JSX, vous pouvez uniquement écrire EXPRESSIONS et pas STATEMENTS comme un for (), déclarer des variables ou des classes, ou une instruction if ().

C'est pourquoi les fonctions CallExpressions sont si présentes aujourd'hui. Mon conseil, s'y habituer. Voici ce que je ferais:

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

filtration:

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

si():

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

sinon:

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

J'espère que ça aide

1
cancerbero

Vous pouvez créer un nouveau composant comme ci-dessous:

transmettez la clé et les données à votre composant ObjectRow comme ceci

export const ObjectRow = ({key,data}) => {
    return (
      <div>
          ...
      </div>
    );
}

créer un nouveau composant ObjectRowList à agir comme un conteneur pour vos données

export const ObjectRowList = (objectRows) => {
    return (
      <tbody>
        {objectRows.map((row, index) => (
          <ObjectRow key={index} data={row} />
        ))}
      </tbody>
    );
}
1
Mselmi Ali

Vous devez écrire en JSX 

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

Il existe de nombreuses solutions publiées qui consistent à itérer un tableau et à générer des éléments jsx. Tous sont bons, mais tous ont utilisé l'index directement en boucle. Il est recommandé d'utiliser un identifiant unique à partir de données en tant que clé, mais lorsque nous n'avons pas d'identifiant unique pour chaque objet du tableau, nous utilisons index en tant que clé, mais il n'est pas recommandé de l'utiliser directement.

Une dernière chose pourquoi nous choisissons .map mais pourquoi pas .foEach car .map renvoie un nouveau tableau. Il existe différentes façons de faire .map ces jours-ci. 

Différentes versions de l'utilisation de .map ci-dessous illustrent en détail comment utiliser une clé unique et comment utiliser .map pour mettre en boucle des éléments jsx.

.map sans retour lors du retour d'un seul élément jsx et d'un identifiant unique à partir de données en tant que version clé

const {objects} = this.state;

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

.map sans retour lors du retour de plusieurs éléments jsx et identifiant unique à partir de données en tant que version clé

const {objects} = this.state;

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

.map sans retour lors du retour d'un seul élément jsx et d'un index en tant que version clé

const {objects} = this.state;

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

.map sans retour lors du retour de plusieurs éléments jsx et index en version clé

const {objects} = this.state;

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

.map avec return lors du retour de plusieurs éléments jsx et index en version clé

const {objects} = this.state;

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

.map avec return lors du retour de plusieurs éléments jsx et identifiant unique à partir des données en tant que version clé

const {objects} = this.state;

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

L'autre façon est 

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

Pour fournir une solution plus simple au cas où vous souhaiteriez utiliser un nombre de lignes spécifique stocké sous la forme Integer-value. Avec l’aide de typedArrays, nous pourrions réaliser la solution souhaitée de la manière suivante.

// 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

Vous pouvez essayer la nouvelle boucle 

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

Voici quelques exemples: https://flaviocopes.com/react-how-to-loop/

0
Bert lucas