未捕获的类型错误:无法读取未定义的属性“结果”-ReactJS

时间:2021-03-04 13:43:39

标签: reactjs

我正在学习 ReactJS,我正在尝试从 API 获取数据,数据已加载,但是在 MovieRow.js 中使用“items.results”时,出现以下错误:

*Uncaught TypeError: 无法读取未定义的属性“结果”。

*警告:列表中的每个孩子都应该有一个唯一的“key”道具。

**

Tmdb.js

const API_KEY = '********************';
const API_BASE = 'https://api.themoviedb.org/3';

const basicFetch = async (endpoint) => {

    const req = await fetch(`${API_BASE}${endpoint}`);
    const json = await req.json();
    return json;
}

export default {
    getHomeList: async () => {
        return [
            {
                slug: 'originais',
                title: 'Originais do Netflix',
                items: await basicFetch(`/discover/tv?with_network=213&language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'trending',
                title: 'Recomendados para você',
                items: await basicFetch(`/trending/all/week?language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'toprated',
                title: 'Em Alta',
                items: await basicFetch (`/movie/top_rated?language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'action',
                title: 'Ação',
                items: await basicFetch (`/discover/movie?with_genres=28&language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'comedy',
                title: 'Comédia',
                items: await basicFetch (`/discover/movie?with_genres=35&language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'horror',
                title: 'Terror',
                itens: await basicFetch (`/discover/movie?with_genres=27&language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'romance',
                title: 'Romance',
                itens: await basicFetch (`/discover/movie?with_genres=10749&language=pt-BR&api_key=${API_KEY}`)
            },
            {
                slug: 'documentary',
                title: 'Documentários',
                itens: await basicFetch (`/discover/movie?with_genres=99&language=pt-BR&api_key=${API_KEY}`)
            },
        ];
    }
}

MovieRow.js

import React from 'react';
import './MovieRow.css';

export default ({title, items}) => {

    return(

        <div>
            <h2>{title}</h2>
            <div className='movieRow--listarea'>
                {items.results.length > 0 && items.results.map((item, key)=> (
                    <img src={`https://image.tmdb.org/t/p/w300${item.poster_path}`}/>
                ))}
            </div>
        </div>
    );
}

**

App.js

import React, { useEffect, useState } from 'react';
import Tmdb from './Tmdb';
import MovieRow from './components/MovieRow';

export default () => {

  const [movieList, setMovieList] = useState([]);

  useEffect(() => {
    const loadAll = async () => {

      let list = await Tmdb.getHomeList();
      setMovieList(list);
    }

    loadAll();
  }, []);

  return (
    <div className='page'>
      <section className='lists'>
        {movieList.map((item, key)=>(
          <MovieRow key={key} title={item.title} items={item.items}/>
        ))}
      </section>
    </div>
  );
}

2 个答案:

答案 0 :(得分:0)

<块引用>

*Uncaught TypeError: 无法读取未定义的属性“结果”。

您的数据中有错别字,itens 而不是 items。这会导致 item.items 未定义,因此,MovieRow 未定义 items,然后您尝试对其进行映射,从而导致错误。

通过在 MovieProp 组件中检查空值以及利用 PropTypes 来告诉 React 每个组件期望什么来防止这些问题是一个好主意,这样您就可以获得更少的神秘错误:

export default function MovieProp({title, items}) {
    return (
        <div>
            <h2>{title}</h2>
            <div className='movieRow--listarea'>
                {items && items.results && items.results.length && items.results.map((item, key)=> (
                    <img src={`https://image.tmdb.org/t/p/w300${item.poster_path}`} key={key} />
                ))}
            </div>
        </div>
    );
}

MovieProp.propTypes = {
  title: PropTypes.node.isRequired,
  items: PropTypes.shape({
    results: PropTypes.arrayOf(PropTypes.shape({
      poster_path: PropTypes.string,
    })).isRequired,
  }).isRequired,
};
<块引用>

*警告:列表中的每个孩子都应该有一个唯一的“key”道具。

您忘记将唯一的 key 添加到在 MovieRow 组件中呈现的 <img> 标签。

旁注:使用索引(.map() 中的第二个参数)作为 React 组件键通常不是一个好主意。在您的情况下,item.slug 可能是一个不错的选择,如果您确定 slug 将是独一无二的。 有关该主题的更多信息:https://reactjs.org/docs/lists-and-keys.html#keys

答案 1 :(得分:0)

出现未定义的错误是因为关键字段中的拼写错误。

itens 而不是 items

为了更安全,请始终检查未定义的情况,

您可以使用可选链,如下所示。

{items?.results?.map((item, key)=> (
    <img key={key} src={`https://image.tmdb.org/t/p/w300${item.poster_path}`}/>))}

阅读更多 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

对于唯一键警告,如果您从响应中获得一个更可取的唯一键,请为图像标签设置一个唯一键。