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>
);
}
CodePudding user response:
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} />
</>
);
})}
CodePudding user response:
You are using the .forEach method - which returns nothing, instead use .map that is identical but does return things
{onlineImages?.map((imageSet, category) =>
<>
<div>Image Category: {category}</div>
<ImageGrid images={imageSet} />
</>
)}