Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to render custom elements for each item in an object (Map data structure) in React TS?

I’ve been using this method to render multiple custom elements from an array but this is my first time doing it using a map data structure. It compiles fine but renders nothing. I’ve set up a codesandbox here.

import "./styles.css";
import React from "react";
import ImageGrid from "./ImageGrid";

interface OnlineImage {
  id: string;
  url: string;
}

export default function App() {
  const [onlineImages, setOnlineImages] = React.useState<Map<string, OnlineImage[]>>();
  
  React.useEffect(() => {
    let onlineImageMap = new Map<string, OnlineImage[]>();

    // fake api call
    onlineImageMap.set("randomImageSet1", [
      { id: "1", url: "https://picsum.photos/200" },
      { id: "2", url: "https://picsum.photos/200" }
    ]);
    onlineImageMap.set("randomImageSet2", [
      { id: "1", url: "https://picsum.photos/200" },
      { id: "2", url: "https://picsum.photos/200" }
    ]);

    // set state
    setOnlineImages(onlineImageMap);
  }, []);

  return (
    <div className="App">
      <div>Below should render my custom ImageGrid for each item in map...</div>
      <>
        {onlineImages?.forEach((imageSet, category) => {
          return (
            <>
              <div>Image Category: {category}</div>
              <ImageGrid images={imageSet} />
            </>
          );
        })}
      </>
    </div>
  );
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Hi Samuel: I think you should first convert the map to an Array and then use the Array.prototype.map method which actually returns a copy of the original array with your function applied to it.

As you probably already figured out the return statement does nothing within a forEach function (to be more exact it only stops the execution of the code but does not bring back anything into the outer context).

If you really want to use forEach you’ll have to use an array or Object to catch it then use Object.entries/.map to iterate over it


const myMap = new Map(Object.entries({a: 1, b: 2}))
const myMapCaptureList = []
myMap.forEach((value, key) => {
myMapCaptureList.push([key, value])
}
// then you can use myMapCaptureList
myMapCaptureList.map(([key, value]) => <div>{key}: <span>{value}</span></div>);

But I would suggest that it is much easier to use the very helpful Array.from method that can help convert a Map into an array of key/value pair entries: [[key1, val1], [key2, val2]]. It is essentially equivalent to running Object.entries(someObject).

{Array.from(onlineImages || []).map(([category, imageSet]) => {
          return (
            <>
              <div>Image Category: {category}</div>
              <ImageGrid images={imageSet} />
            </>
          );
        })}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading