Выравнивание вложенного словаря реагирует? — Не удается прочитать свойство ‘standard’ неопределенного

#javascript #reactjs #api #axios #fetch

#javascript #reactjs #API #axios #выборка

Вопрос:

Я работаю над личным проектом веб-приложения в React. Я новичок в этой технологии, но очень хочу ее изучить. Я столкнулся с проблемой. Я использую axios для извлечения данных из ответа API Google Youtube, и это работает, но я не могу проанализировать полученные вложенные данные. Что я имею в виду под этим: внутри элементов есть несколько фрагментов

 {
    "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/nnJeżeli dzisiejszym odcinek Ci się spodobał zostaw like'a albo subskrybcję :DnFanPage:nhttp://facebook.com/RuchOpornikownGoogle :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"
                }
            }
        },
  

Я хочу получить случайный фрагмент из элементов и использовать его атрибут заголовка, описание и эскизы.
На данный момент я могу получить доступ к описанию и названию, но получить доступ к movie.description.thumbnails.standard.url или movie.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;
  

Знаете ли вы, что может быть ошибкой и как ее исправить? Консоль.log и JSON.stringify показывают, что эти атрибуты есть.

Комментарии:

1. Ваше movie состояние — это массив, но вы ссылаетесь на него, как на объект в вашей логике рендеринга. movie.snippet и movie.thumbnails , очевидно, будет неопределенным.

2. Как получить доступ к этим элементам?

3. Ответ ниже, но при первоначальном рендеринге movie это массив и не будет иметь свойств, которые я вызвал. Преобразование его в пустой объект приблизит вас, но задержит «неопределенное» значение при дальнейшей ссылке на ваш объект состояния, что приведет к добавлению некоторых нулевых проверок.

Ответ №1:

Проблема (ы)

Ваше начальное movie состояние — это массив, но вы ссылаетесь на него, как на объект в вашей логике рендеринга. movie.snippet и movie.thumbnails , очевидно, будет неопределенным.

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

и

 movie.thumbnails.standard.url
  

Решение

  1. Приведите тип начального состояния в соответствие с тем, до чего он обновляется из запроса на выборку, и как к нему обращаются в логике рендеринга, т.Е. Объект

     const [movie, setMovie] = useState({});
      
  2. Используйте надлежащие проверки null и предоставьте резервные значения.

Проверки Null

 movie.thumbnails amp;amp; movie.thumbnails.standard amp;amp; movie.thumbnails.standard.url || ""
  

или с использованием необязательной цепочки и объединения нулей

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

Комментарии:

1. Итак, что я сделал неправильно, пытался получить доступ к элементу массива, как если бы это был объект js, но элемента просто не было из-за природы структуры данных. И решение состояло в том, чтобы получить доступ к типу изменения с [] на { } object , это правильно?

2. @szymonindy Да, это была половина проблемы. Объекты представляют собой ассоциированные массивы пар ключ-значение, вы можете думать о массивах как о специальных объектах, где ключами являются индексы массива. Массив не будет иметь индекса с именем «thumbnails», movie["thumbnails"] // undefined т. Е. При более глубоком доступе к неопределенному объекту, когда вы увидите ошибку, которая у вас была.

Ответ №2:

вы получаете ошибку, потому что перед получением каких-либо данных ваш объект movie пуст. вы должны проверить, прежде чем обращаться к вложенным свойствам. вот так

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

Ответ №3:

movie?.thumbnails?.standard?.url должен это сделать. Похоже movie.thumbnails , это undefined

Ответ №4:

предполагая movie , что содержит правильные данные, синтаксис должен работать. Вот тест: https://jsfiddle.net/yf470pma/1 /

Я бы добавил точку останова и проверил, что там на самом деле.

Ответ №5:

initial movie — это пустой массив, и для извлечения из API. refactor потребуется некоторое время для приведения к приведенному ниже

   const [movie, setMovie] = useState();
  

и проверьте movie, если оно не равно null перед рендерингом

 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;