开发者问题收集

React 中的 API 调用“TypeError:无法读取未定义的属性(读取‘map’)”

2022-07-11
2987

我正尝试使用通过 API 调用检索到的数组中的数据填充对象列表。我确实获得了正确的数据(可以 console.log 该对象),但在代码中使用它不起作用。我尝试了多种解决方案,但到目前为止都没有奏效,我陷入了困境,在花另外 2 天时间之前,我想寻求您的帮助。我相信这是一件我还没有学会的简单的事情。

TypeError:无法读取未定义的属性(读取“map”)

const EventCarousel = () => {
  const [data, setData] = useState([]);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    axios

      .get(
        "https://cdn.contentful.com/spaces/qqdjjpwbe10z/environments/master/entries?access_token=PRIVATE_TOKEN"
      )
      .then((res) => {
        console.log(res.data.items[0].fields.imageUrl);
        setData(res.data);
      })
      .catch((error) => {
        setError(error.message);
      })
      .finally(() => {
        setLoading(false);
      });
  }, []);

if (loading) {
    return <p>Data is loading...</p>;
  } else
    return (

 {data.items.map((item) => (
            <div>
              <Event
                imageUrl={item.fields.imageUrl}
                title={item.fields.title}
                text={item.fields.text}
                linkUrl={item.fields.linkURL}
                location={item.fields.location}
                date={item.fields.date}
              />
            </div>
          ))}

JSON 结构如下所示:

{
"sys": {},
"total": 2,
"skip": 0,
"limit": 100,
"items": [
{
"metadata": {},
"sys": {},
"fields": {
"title": "Second Event",
"text": "This is decription of a second event",
"imageUrl": "https://i.imgur.com/ULO8mVt.png",
"linkUrl": "https://www.moabit.world",
"location": "Second Location",
"date": "second date"
}
},
{
"metadata": {},
"sys": {},
"fields": {
"title": "First Event",
"text": "This is first fetched text",
"imageUrl": "https://i.imgur.com/ULO8mVt.png",
"linkUrl": "https://www.facebook.com",
"location": "First location",
"date": "First date"
}
}
]
}

谢谢

2个回答

这是因为当您的组件被挂载时,它没有 data.items 字段,因为您的初始数据将是 []

您需要先将初始状态设置为包含 { ,然后更新 data.items 以有条件地运行。

尝试以下解决方案:

const EventCarousel = () => {
  const [data, setData] = useState({});
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    axios

      .get(
        "https://cdn.contentful.com/spaces/qqdjjpwbe10z/environments/master/entries?access_token=PRIVATE_TOKEN"
      )
      .then((res) => {
        console.log(res.data.items[0].fields.imageUrl);
        setData(res.data);
      })
      .catch((error) => {
        setError(error.message);
      })
      .finally(() => {
        setLoading(false);
      });
  }, []);

if (loading) {
    return <p>Data is loading...</p>;
  } else
    return (

 {data?.items?.length ? data.items.map((item) => (
            <div>
              <Event
                imageUrl={item.fields.imageUrl}
                title={item.fields.title}
                text={item.fields.text}
                linkUrl={item.fields.linkURL}
                location={item.fields.location}
                date={item.fields.date}
              />
            </div>
          )) : null}
Mr.Online
2022-07-11

您将状态初始化为数组 useState([]) ,但将其用作对象 data.items ,请选择其中之一:

const [data, setData] = useState({items: []});
setData(res.data)

// Or
const [data, setData] = useState([]);
setData(res.data.items)
Dennis Vash
2022-07-11