开发者问题收集

无法映射/列出从 YouTube API 获取的数组

2020-04-30
146

我一直在尝试从 YouTube API 获取视频,但似乎每当我尝试获取它们时,map 函数似乎都不起作用。( TypeError:无法读取未定义的属性“map”

代码成功从 此处 获取数组列表,但无法从 YouTube 获取。

我怀疑问题发生的原因是 YouTube 提供的数组位于 [items] 对象内。

这是我的代码:

PopularApp.js

import React, { Component, useState, useEffect } from 'react';
import PopularVid from "./components/PopularVid";
import axios from 'axios';

const PopularApp = () => {
    const [video, setVideo] = useState([]);
    const hotVids = video.items;
    const [loading, setLoading] = useState(false);
    const [currentPage, setCurrentPage] = useState(1);
    const [vidsPerPage, setVidsPerPage] = useState(10);

    useEffect(() => { //whenever this function runs, it will run this/fetch data from API, neverending loop
        const fetchPosts = async () => {
            setLoading();
            const res = await axios.get('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&chart=mostPopular&maxResults=12&key=myapikey');
            setVideo(res.data);
            setLoading(false);
        }
        fetchPosts();
    }, []);

    console.log(hotVids);

    return(
        <div>
            <PopularVid videos={hotVids} loading={loading}/>
        </div>
    )
}

export default PopularApp;

PopularVid.js

import React from 'react';

const PopularVid = ({videos, loading}) => {
    if(loading){
        return <div>Loading...</div>
    }

    return <ul>
        {videos.map(video=>(
            <li key={video.id}>
                {video.snippet.title}
            </li>
        ))}
    </ul>;
}

export default PopularVid;

这是我尝试解析的 YouTube json 文件的示例:

{
  "kind": "youtube#videoListResponse",
  "etag": "_Y60U4EX77fYwquDNkByKBxEGC8",
  "items": [
    {
      "kind": "youtube#video",
      "etag": "V8SLDA5Sop7jpKOC9NnsckQoOwM",
      "id": "lEIqjoO0-Bs",
      "snippet": {
        "publishedAt": "2020-04-29T19:06:00Z",
        "channelId": "UCKrdjiuS66yXOdEZ_cOD_TA",
        "title": "Video #1",
        "description": "This is the description",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/lEIqjoO0-Bs/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/lEIqjoO0-Bs/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/lEIqjoO0-Bs/hqdefault.jpg",
            "width": 480,
            "height": 360
          },
          "standard": {
            "url": "https://i.ytimg.com/vi/lEIqjoO0-Bs/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/lEIqjoO0-Bs/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "channelTitle": "Channel",
        "categoryId": "10",
        "liveBroadcastContent": "none",
      },
      "statistics": {
        "viewCount": "4633587",
        "likeCount": "349875",
        "dislikeCount": "6602",
        "favoriteCount": "0",
        "commentCount": "27237"
      }
    },
    {
      "kind": "youtube#video",
      "etag": "2KGplnTU4KAR0gTjmL8nXnzlK34",
      "id": "XRNjRcKZc1A",
      "snippet": {
        "publishedAt": "2020-04-29T16:00:30Z",
        "channelId": "UC47kJWRBD-NREBvmBg5kWeA",
        "title": "Video #2",
        "description": "Description #2",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/XRNjRcKZc1A/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/XRNjRcKZc1A/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/XRNjRcKZc1A/hqdefault.jpg",
            "width": 480,
            "height": 360
          },
          "standard": {
            "url": "https://i.ytimg.com/vi/XRNjRcKZc1A/sddefault.jpg",
            "width": 640,
            "height": 480
          },
          "maxres": {
            "url": "https://i.ytimg.com/vi/XRNjRcKZc1A/maxresdefault.jpg",
            "width": 1280,
            "height": 720
          }
        },
        "channelTitle": "King Von",
        "categoryId": "10",
        "liveBroadcastContent": "none",
        "defaultAudioLanguage": "en"
      },
      "statistics": {
        "viewCount": "901039",
        "likeCount": "62449",
        "dislikeCount": "1862",
        "favoriteCount": "0",
        "commentCount": "5184"
      }
    }
  ],
  "nextPageToken": "CAIQAA",
  "pageInfo": {
    "totalResults": 200,
    "resultsPerPage": 2
  }
}
2个回答

res.data 是一个对象,您不能将其用于对象,但可以将其用于数组。我认为您需要映射的是 res.data.items

codex
2020-04-30

两件事:

  • hotVids 的初始值未定义。( [].items )。获取数据后应该没问题。

  • loading 永远不会为真。看起来您打算在 useEffect 中将其设置为 true。您也可以使用 useState 将其初始化为 true。

要处理尚未加载的数据,您通常会做以下两件事之一:设置一个合理的默认值(如空数组),可以成功渲染;或者阻止渲染,直到加载完成(如您的加载变量)。

Ben West
2020-04-30