axios 扁平化嵌套字典React?- 无法读取未定义的属性“standard”

uidvcgyl  于 2023-08-04  发布在  iOS
关注(0)|答案(5)|浏览(97)

我正在用React做一个个人的WebApp项目。我对这项技术很陌生,但我非常渴望学习它。我遇到了一个问题。我正在使用axios从Google YouTube API响应中获取数据,它可以工作,但我无法解析嵌套的数据。我的意思是:内部项目有多个片段

{
    "items": [
        {
            "snippet": {
                "title": "Dolby Atmos - usłysz więcej!",
                "description": "W dzisiejszym odcinku opowiem wam o tym czym jest nagłośnienie i system dolby atmos. System i nagłośnienie Dolby atmos znajdziemy obecnie w najlepszych kinach. System wspierają takie filmy jak \"Zjawa\" czy \"Kapitan Ameryka wojna bohaterów\". Jakość dźwięk docenią kinomani i prawdziwi audiofile. Istnieje również stworzenia systemu składającego się z głośników dolby atmos kina domowego, ale jest poważna inwestycja.\nJeżeli jesteś z Łodzi i chcesz poczuć Dolby Atmos na własnej skórze kliknij tutaj:\nhttp://www.helios.pl/47,Lodz/StronaGlowna/\n\nJeżeli dzisiejszym odcinek Ci się spodobał zostaw like'a albo subskrybcję :D\nFanPage:\nhttp://facebook.com/RuchOpornikow\nGoogle+:\nhttps://plus.google.com/u/0/+RuchOpor...\nTwitter:\nhttps://twitter.com/RuchOpornikow",
                "thumbnails": {
                    "standard": {
                        "url": "https://i.ytimg.com/vi/QWTk3vnztRw/sddefault.jpg",
                        "width": 640,
                        "height": 480
                    },
                    "maxres": {
                        "url": "https://i.ytimg.com/vi/QWTk3vnztRw/maxresdefault.jpg",
                        "width": 1280,
                        "height": 720
                    }
                },
                "resourceId": {
                    "videoId": "QWTk3vnztRw"
                }
            }
        },

字符串
我想得到一个随机片段的项目,并使用它的标题属性,描述和缩略图。此时我可以访问description和title,但访问movie.description.thumbnails.standard.urlmovie.resourceId.videoId时出现错误:

TypeError: Cannot read property 'standard' of undefined
  31 |     backgroundPosition: "center center",
  32 |   }}
  33 | >
> 34 |   <img src ={`${movie.thumbnails.standard.url}`}/>
  35 |     <div className="banner_contents">
  36 |     {/* edge cases */}
  37 |     <h1 className="banner_title">


以下是我的完整代码:

function Banner() {
  const [movie, setMovie] = useState([]);
  useEffect(() => {
    async function fetchData() {
      const request = await axios.get("./data.json");
      setMovie(
        request.data.items[
          Math.floor(Math.random() * (request.data.items.length-1))
        ].snippet
      );

      return request;
    }
    fetchData();
  }, []);
  return (
    <header
      className="banner"
      style={{
        backgroundSize: "cover",
        // backgroundImage: `url("${movie.snippet.thumbnails.maxres.url}")`,
        backgroundPosition: "center center",
      }}
    >
      <img src ={`${movie.thumbnails.standard.url}`}/>
      <div className="banner_contents">
        {/* edge cases */}
        <h1 className="banner_title">
          {movie.title}
        </h1>
        <div className="banner_buttons">
          <button className="banner_button">Play</button>
          <button className="banner_button">Original</button>
        </div>
        <h1 className="banner_description">{movie.description}</h1>
      </div>
      <div className="banner--fadeBottom" />
    </header>
  );
}

export default Banner;


你知道什么可能是错误以及如何修复它吗?Console.logJSON.stringify表明这些属性存在。

wwtsj6pe

wwtsj6pe1#

问题

您的初始movie状态是一个数组,但您引用它时将其视为呈现逻辑中的一个对象。movie.snippetmovie.thumbnails显然是未定义的。

const [movie, setMovie] = useState([]);

字符串
和/或

movie.thumbnails.standard.url

溶液

1.使初始状态类型与从获取请求更新到的状态类型以及在呈现逻辑中访问的方式相匹配,即一个物体

const [movie, setMovie] = useState({});


1.使用适当的空值检查并提供回退值。
空检查

movie.thumbnails && movie.thumbnails.standard && movie.thumbnails.standard.url || ""


或使用可选链接和空合并

movie?.thumbnails?.standard?.url ?? ""

5n0oy7gb

5n0oy7gb2#

你得到错误,因为在得到任何数据之前,你的电影对象是空的。你应该在访问嵌套属性之前进行检查。像这样

<img src ={movie.thumbnails ? `${movie.thumbnails.standard.url}` : ""}/>

字符串

xwmevbvl

xwmevbvl3#

movie?.thumbnails?.standard?.url应该可以。movie.thumbnailsundefined

qvtsj1bj

qvtsj1bj4#

假设movie包含正确的数据,语法应该工作。这里有一个测试:https://jsfiddle.net/yf470pma/1/
我会添加一个断点并检查那里到底有什么。

ctrmrzij

ctrmrzij5#

initial movie是一个空数组,从API中获取需要一些时间。重构到下面

const [movie, setMovie] = useState();

字符串
并在渲染前检查电影是否为空

return movie?(
<header
  className="banner"
  style={{
    backgroundSize: "cover",
    // backgroundImage: `url("${movie.snippet.thumbnails.maxres.url}")`,
    backgroundPosition: "center center",
  }}
>
  <img src ={`${movie.thumbnails.standard.url}`}/>
  <div className="banner_contents">
    {/* edge cases */}
    <h1 className="banner_title">
      {movie.title}
    </h1>
    <div className="banner_buttons">
      <button className="banner_button">Play</button>
      <button className="banner_button">Original</button>
    </div>
    <h1 className="banner_description">{movie.description}</h1>
  </div>
  <div className="banner--fadeBottom" />
</header>
):null;

相关问题