我正在学习 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>
);
}
答案 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
对于唯一键警告,如果您从响应中获得一个更可取的唯一键,请为图像标签设置一个唯一键。