如何在 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} />
            </>
          );
        })}