【问题标题】:React JS - data.map can't create list with the dataReact JS - data.map 无法使用数据创建列表
【发布时间】:2020-02-22 01:26:29
【问题描述】:

我收到了 data.js 文件,其中包含一些食物的基本信息,例如:

export default [
    {
        "name": "Crock Pot Roast",
        "information":[
            {
                "date":"24 July 2019",
                "type": "Main dish",
                "difficulty": "Easy",
                "time": "~50",
            }
        ],
        "ingredients": [
            {
                "quantity": "1",
                "name": " beef roast",
                "type": "Meat"
            }
        ],
        ...
        Some more data
        ...
    }
   ]

我想在 react 上创建可以从 data.information 获取所有元素的列表,哪个函数可以正确使用?

我得到这样的数据:

const getData = data.map(food => {
    return (
        <div key={food.name}>
            <span>{food.name}</span>
            <div>
                <div>
                    <img src={food.imageURL} alt={food.name} />
                    <div>
                        <ul>{getFoodInformation}</ul>
                    </div>
                </div>
            </div>

            <div>food ingredients</div>

            <div>food recipe</div>
        </div>
    );
});

但我不能使用food.information.map 来创建如下列表:

<ul>{food.information.map((info) => <div key={info.date}>{info}</div>) }</ul>

有什么想法可以使用其他功能而不是地图吗?

【问题讨论】:

  • 这能回答你的问题吗? How to iterate over a JavaScript object?
  • 对于 {getFoodInformation} 的值,您的理想/预期 HTML 是什么样的?每个属性是否应该包含在单独的 &lt;li /&gt; 中?

标签: javascript reactjs list


【解决方案1】:

你说得对,这条线是问题所在:

<ul>{food.information.map((info) => <div key={info.date}>{info}</div>) }</ul>

但是.map() 不是问题。你的 information 数据 一个数组,所以你可以用 JSX .map() 它。

你的问题是这样的:

<div key={info.date}>{info}</div>

info 是一个对象,React 不知道如何“漂亮”地打印一个对象。您想使用字符串数据(例如,{info.type})。

如果您需要转储整个对象,请像这样使用JSON.stringify

<div key={info.date}>{JSON.stringify(info)}</div>

【讨论】:

  • 这种方法有效...我真的希望有更漂亮的方式来获取数据,然后创建列表
  • 你可以编写一个漂亮的方法,以你想要的任何格式打印数据,但基线是 React 不知道如何打印对象。实际上,没有人会知道您通过输入&lt;div&gt;{object}&lt;/div&gt; 会显示什么。
【解决方案2】:

默认情况下,React 不会将数组/对象渲染到列表中。你必须在你的代码中明确。

您的第一次尝试是“接近”纠正,但是,您可以注意到,成分和信息都是对象数组。这意味着您必须为每个索引生成一个标签。

我使用 JSON.stringify 生成唯一键,因为使用索引作为键是不好的做法。

下面的代码向您展示了使用 react 的正确方法之一。

        const data = [
      {
        name: "Crock Pot Roast",
        imageURL: "https://via.placeholder.com/150",
        information: [
          {
            date: "24 July 2019",
            type: "Main dish",
            difficulty: "Easy",
            time: "~50"
          }
        ],
        ingredients: [
          {
            quantity: "1",
            name: " beef roast",
            type: "Meat"
          }
        ]
      }
    ];

    const CardRecipe = ({data}) => {
      const { name, imageURL, information, ingredients } = data;
      return (
        <div key={name}>
          <span>{name}</span>
          <div>
            <div>
              <img src={imageURL} alt={name} />
              <div>
                {information &&
                  information.map(info => {
                    const { date, type, difficulty, time } = info;
                    return (
                      <ul key={JSON.stringify(info)}>
                        <li> {date} </li>
                        <li> {type} </li>
                        <li> {difficulty} </li>
                        <li> {time} </li>
                      </ul>
                    );
                  })}
              </div>
              <div>
                {ingredients &&
                  ingredients.map(ingredient => {
                    const { quantity, name, type } = ingredient;
                    return (
                      <ul key={JSON.stringify(ingredient)}>
                        <li> {quantity} </li>
                        <li> {name} </li>
                        <li> {type} </li>
                      </ul>
                    );
                  })}
              </div>
            </div>
          </div>

          <div>food ingredients</div>

          <div>food recipe</div>
        </div>
      );
    };

    export default function App() {
      const first_reciepe = data[0];
      return (
        <div className="App">
          <CardRecipe data={first_reciepe} />
        </div>
      );
    }

或者,您可以通过在数组上映射一次来打印任何列表,然后在每个对象/键上生成 (x) 个 标记。

例子:

const DoList = ({ data }) => {
  return data.map(list => {
    return (
      <ul key={list}>
        {Object.keys(list).map(key => {
          const value = list[key];
          return <li key={key}> {value} </li>;
        })}
      </ul>
    );
  });
};

然后你可以像这样使用它尽可能多的时间:

<DoList data={ingredients} />
<DoList data={information} />
<DoList data={...} />

【讨论】:

  • 我试过你的方法只需要添加:``` return (
  • {date}
  • {type}
  • {difficulty}
  • {time}
  • ) ```它不会给我错误,但数据永远不会显示...
        食材
        食谱
        DOM查看之后像这样,但 ul 是空的。
    • @A.Salim 确实,我的代码有点粗略,昨晚写得很晚。我会在一分钟内更新,感谢您指出问题。
    • 如果您可以查看最后一条评论,我会添加另一种方式数据...不确定我应该使用 JSON.stringify()....
    • 您不必强制使用 stringify,您可以使用您拥有的属性之一作为键。我检查了你的编辑。与其他 for/each 循环不同,如果不映射为 map 返回元素,就不可能做到这一点。 Map 是生成新 html 元素的最简洁方式。最终,您可以做的更简洁一点的是编写第二个可重用组件,该组件将专门处理列表
    • 猜你喜欢
      相关资源
      最近更新 更多
      热门标签