开发者问题收集

如何映射对象内部的数组

2021-08-02
387

我正在学习 ReactJS 并练习使用不同的 API 来获取数据并使用它。虽然我正在处理这个 flickr API,它返回的数据类似于“对象内的数组”

{
  "photos": {
    "page": 1,
    "pages": 10,
    "perpage": 100,
    "total": "1000",
    "photo": [
      {
        "id": "51351784082",
        "owner": "10706882@N07",
        "secret": "4b8734223e",
        "server": "65535",
        "farm": 66,
        "title": "Walnuts topping and bread",
        "ispublic": 1,
        "isfriend": 0,
        "isfamily": 0
      },
      {
        "id": "51351786287",
        "owner": "131221068@N03",
        "secret": "cb4e315e52",
        "server": "65535",
        "farm": 66,
        "title": "Amapola Flyg / Fokker 50 / SE-MFY / EIDW",
        "ispublic": 1,
        "isfriend": 0,
        "isfamily": 0
      }
    ]
  },
  "stat": "ok"
}

我想访问照片数组,通过其属性(如 secret 和 id)进行映射,以生成图像链接,最终显示图像。但是从 API 返回的数据是一个具有数组的对象,我无法访问它。它给了我错误。请检查代码:

import "./App.css";
import React, { useEffect, useState } from "react";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";

function App() {
  const [variable, setImgdata] = useState([]);

  useEffect(() => {
    fetch(
      "https://www.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=09d770a1c3e5e480517dff043f458023&format=json&nojsoncallback=1&auth_token=72157719623454163-39de62921689545c&api_sig=faf58b987d668d8b3cf264807a687c9b"
    )
      .then((response) => response.json())
      .then((data) => {
        const variable = data.photos.photo.map((imgdata) => ({
          id: imgdata.photos.photo.id,
          secret: imgdata.photos.photo.secret,
          title: imgdata.photos.photo.title,
        }));
        setImgdata(variable);
      });
  });

  return (
    <div className="App">
      <h1>Testing Here</h1>
      {variable.map((img) => (
        <div className="card" style={{ width: "18rem" }}>
          <img
            src={`https://live.staticflickr.com/65535/${img.id}_${img.secret}_w.jpg`}
            className="card-img-top"
            alt="..."
          />
          <div className="card-body">
            <h5 className="card-title">{img.title}</h5>
          </div>
        </div>
      ))}
    </div>
  );
}

export default App;

/*
const data = response.json();
const data_array = Object.keys(data);
console.log(data_array);
*/

它给了我这样的错误:

Unhandled Rejection (TypeError): Cannot read property 'photo' of undefined

它无法读取照片数组。请帮我看看我在这里做错了什么。 修复此代码将有很大帮助

2个回答

当映射数组时,您将遍历各个项目: photo 不是单个数组元素的属性,而是主对象的属性。

直接使用:

id: imgdata.id,
        secret: imgdata.secret,
        title: imgdata.title,
Tushar Shahi
2021-08-02

虽然您已经得到了答案,但是您的代码中还有一些问题。

  1. 在使用 useEffect 钩子时传递依赖项数组,否则会导致不必要的重新渲染。

  2. 在地图内创建列表时添加 key 属性。

  3. 您可以使用解构从 imgdata 数据对象中获取键的值

function App() {
    const [variable, setImgdata] = useState([]);

    useEffect(() => {
        fetch(
            "https://www.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=09d770a1c3e5e480517dff043f458023&format=json&nojsoncallback=1&auth_token=72157719623454163-39de62921689545c&api_sig=faf58b987d668d8b3cf264807a687c9b"
        )
            .then((response) => response.json())
            .then((data) => {

                const variable = data.photos.photo.map((imgdata) => {                    // destructuring 
                    const {id, secret, title} = imgdata;
                    return {id, secret, title}
                });
                setImgdata(variable);
            });
    }, []); // dependency array

    return (
        <div className="App">
            <h1>Testing Here</h1>
            {variable.map((img) => (
                <div className="card" style={{width: "18rem"}} key={img.id}> // added key prop
                    <img
                        src={`https://live.staticflickr.com/65535/${img.id}_${img.secret}_w.jpg`}
                        className="card-img-top"
                        alt="..."
                    />
                    <div className="card-body">
                        <h5 className="card-title">{img.title}</h5>
                    </div>
                </div>
            ))}
        </div>
    );
}
brk
2021-08-02