【问题标题】:Uncaught TypeError: Cannot read property 'results' of undefined - ReactJS未捕获的类型错误:无法读取未定义的属性“结果” - ReactJS
【发布时间】:2021-03-04 13:43:39
【问题描述】:

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

*Uncaught TypeError: Cannot read property 'results' of undefined.

*警告:列表中的每个孩子都应该有一个唯一的“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>
  );
}

【问题讨论】:

标签: reactjs


【解决方案1】:

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

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

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

【讨论】:

  • 正如你所说,这是一个没有引起注意的错字,我更改了名称并使用了链接,它起作用了,谢谢。
【解决方案2】:

*Uncaught TypeError: Cannot read property 'results' of undefined.

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

最好通过在 MovieProp 组件中检查 null 以及利用 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 组件中呈现的 &lt;img&gt; 标记。

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

【讨论】:

    猜你喜欢
    • 2016-08-09
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 2016-06-09
    相关资源
    最近更新 更多