forEach over es6 Map in JSX

I had a javascript array that was rendering components using array.map. I switched this array to an es6 Map in order to be able to use key-value pairs to find items more easily, and switched from a .map to a forEach over the Map. Inside the forEach I call a render method that returns a React component, but it isn’t being rendered. How do I render a component inside the forEach?

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

Here is the renderGalleryItem method:

  • forEach() and Apply() methods for two dimensional array javascript
  • I try to assign an arraylike collection of elements to variables, whats wrong with my code?
  • Do something with .each id of a string broken by ,
  • What is the difference between .map, .every, and .forEach?
  • Javascript Matrix Calculator with HTML form
  • Does javascript array.forEach traverse elements in ascending order
  • renderGalleryItem = (item, index) => {
        const { gridItemSelected, itemThumbnailRequested } = this.props;
        return (<GalleryItem key={index}
            item={item}
            onClick={gridItemSelected}
            fetchThumbnailFunc={itemThumbnailRequested}
        />);
    };
    

    I understand that forEach doesn’t return anything but does that mean I can’t render inside it?

  • Context and variable scope in ES6 loops and forEach
  • Reset arrays value inside angular.foreach loop
  • JavaScript, Node.js: is Array.forEach asynchronous?
  • Programatically the best solution to determine if for loop can be run on object
  • What is the difference between 'for…in' and 'for each…in' in javascript?
  • Why is native javascript array forEach method significantly slower than the standard for loop?
  • 3 Solutions collect form web for “forEach over es6 Map in JSX”

    You are correct, forEach doesn’t return anything, use map instead, it will return an array of JSX components.

    Map will allow you to access the key as well: resultsByGuid.map((item, key) => { })

    Edit I apologize for jumping the gun and not reading that you were using a Map data structure. forEach won’t render anything because you need the return value, you could implement your own Array.map like iterator:

    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 And thanks to @zerkms for pointing out what should’ve been obvious to me:

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

    If you call .entries() on your map you will get an insertion ordered array which for every key/value pair contains an array with the structure: [key, value]

    So you could just do:

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

    I am still wondering, if there’s a simpler solution though.

    another option, where options is an es6 Map() ..

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