web-dev-qa-db-fra.com

forEach over es6 Map dans JSX

J'avais un tableau javascript qui rendait les composants à l'aide de array.map. J'ai basculé ce tableau vers un es6 Map afin de pouvoir utiliser des paires clé-valeur pour trouver plus facilement des éléments, et je suis passé d'un .map vers un forEach sur la carte. A l'intérieur du forEach j'appelle une méthode de rendu qui retourne un composant React, mais il n'est pas rendu. Comment rendre un composant à l'intérieur du forEach ?

<div className='gallery__items'>
    {resultsByGuid.forEach((result, index) => {
        key++;
        this.renderGalleryItem(result, key);
    })} 
</div>

Voici la méthode renderGalleryItem:

renderGalleryItem = (item, index) => {
    const { gridItemSelected, itemThumbnailRequested } = this.props;
    return (<GalleryItem key={index}
        item={item}
        onClick={gridItemSelected}
        fetchThumbnailFunc={itemThumbnailRequested}
    />);
};

Je comprends que forEach ne renvoie rien, mais cela signifie-t-il que je ne peux pas effectuer de rendu à l'intérieur?

14
alsoALion

Vous avez raison, forEach ne renvoie rien, utilisez map à la place, il renverra un tableau de composants JSX.

La carte vous permettra également d'accéder à la clé: resultsByGuid.map((item, key) => { })

Edit Je m'excuse d'avoir sauté le pistolet et de ne pas avoir lu que vous utilisiez une structure de données Map. forEach ne rendra rien car vous avez besoin de la valeur de retour, vous pouvez implémenter votre propre Array.map comme itérateur:

const mapIterator = (map, cb) => {
  const agg = [];
  for(let [key, value] of map) {
    agg.Push(cb(value, key));
  }
  return agg;
};

<div className='gallery__items'>
  {mapIterator(resultsByGuid, (result, index) => {
    key++;
    return this.renderGalleryItem(result, key);
  })}
</div>

Edit 2 Et merci à @zerkms d'avoir souligné ce qui aurait dû être évident pour moi:

<div className='gallery__items'>
  {Array.from(resultsByGuid.values()).map((result, index) => {
    key++;
    return this.renderGalleryItem(result, key);
  })}
</div>
12
Rob M.

Juste une légère amélioration sur l'exemple de danday74 utilisant la déstructuration des tableaux. Avec des options, la carte ES6:

<select>
  {
    [...options].map(([key, value]) => {
      return <option key={ key } value={ key }>{ value }</option>
    })
  }
</select>
9
BrechtVds

une autre option, où options est une carte es6 () ..

<select>
  {
    [...options].map((entry) => {
      let key = entry[0]
      let value = entry[1]
      return <option key={ key } value={ key }>{ value }</option>
    })
  }
</select>
5
danday74

Si vous appelez .entries() sur votre carte, vous obtiendrez un objet itérateur qui pour chaque paire clé/valeur contient un tableau avec la structure: [key, value] comme mentionné ici .

Vous pouvez donc simplement faire:

<div className='gallery__items'>
  {resultsByGuid.entries().map((result) => {
    return this.renderGalleryItem(result[1], result[0]);
  })}
</div>

Je me demande toujours s'il existe une solution plus simple.

2
Michael Ziörjen