如何在 React TS 中为对象(地图数据结构)中的每个项目呈现自定义元素?
How to render custom elements for each item in an object (Map data structure) in React TS?
我一直在使用这种方法从数组中呈现多个自定义元素,但这是我第一次使用地图数据结构来实现。它编译得很好,但什么也没有呈现。我设置了一个 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>
);
}
您正在使用 .forEach 方法 - return没什么,而是使用相同但做 return 事情
的 .map
{onlineImages?.map((imageSet, category) =>
<>
<div>Image Category: {category}</div>
<ImageGrid images={imageSet} />
</>
)}
你好 Samuel:我认为你应该首先将地图转换为数组,然后使用 Array.prototype.map
方法,该方法实际上 returns 应用了你的函数的原始数组的副本。
你可能已经发现 return
语句在 forEach
函数中什么都不做(更准确地说,它只是停止代码的执行,但不会将任何东西带回外部上下文)。
如果你真的想使用 forEach,你必须使用数组或对象来捕获它,然后使用 Object.entries/.map 对其进行迭代
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>);
但我建议使用非常有用的 Array.from
方法要容易得多,该方法可以帮助将 Map 转换为 key/value 对条目的数组:[[key1, val1], [key2, val2]]
。它本质上等同于 运行 Object.entries(someObject)
.
{Array.from(onlineImages || []).map(([category, imageSet]) => {
return (
<>
<div>Image Category: {category}</div>
<ImageGrid images={imageSet} />
</>
);
})}
我一直在使用这种方法从数组中呈现多个自定义元素,但这是我第一次使用地图数据结构来实现。它编译得很好,但什么也没有呈现。我设置了一个 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>
);
}
您正在使用 .forEach 方法 - return没什么,而是使用相同但做 return 事情
的 .map {onlineImages?.map((imageSet, category) =>
<>
<div>Image Category: {category}</div>
<ImageGrid images={imageSet} />
</>
)}
你好 Samuel:我认为你应该首先将地图转换为数组,然后使用 Array.prototype.map
方法,该方法实际上 returns 应用了你的函数的原始数组的副本。
你可能已经发现 return
语句在 forEach
函数中什么都不做(更准确地说,它只是停止代码的执行,但不会将任何东西带回外部上下文)。
如果你真的想使用 forEach,你必须使用数组或对象来捕获它,然后使用 Object.entries/.map 对其进行迭代
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>);
但我建议使用非常有用的 Array.from
方法要容易得多,该方法可以帮助将 Map 转换为 key/value 对条目的数组:[[key1, val1], [key2, val2]]
。它本质上等同于 运行 Object.entries(someObject)
.
{Array.from(onlineImages || []).map(([category, imageSet]) => {
return (
<>
<div>Image Category: {category}</div>
<ImageGrid images={imageSet} />
</>
);
})}