TypeError:无法读取未定义的属性(读取“地图”),以及 React.js 中的多个 API 请求
Posted
技术标签:
【中文标题】TypeError:无法读取未定义的属性(读取“地图”),以及 React.js 中的多个 API 请求【英文标题】:TypeError: Cannot read properties of undefined (reading 'map'), and multiple API requests in React.js 【发布时间】:2021-12-26 07:32:37 【问题描述】:我知道这个地图阅读错误之前在这里被问过很多,我查看了几个已关闭的问题,但由于它们的原因与我的不同,我选择打开一个新主题。目前我面临 2 个错误,所以让我一次解决一个。
我想要完成的事情:
提交搜索查询后,应该呈现“结果”组件并向我的后端发出 GET
请求(反过来,它将向外部 API 发出 GET
请求并将结果发送回 React )。一旦它获取数据,它应该将其存储在details
变量中,该变量将被映射并呈现在子组件中。
第一个问题:
尽管向我的后端和外部 API 发出了成功的请求(我可以使用 console.log
进行检查),但检索到的数据似乎没有存储在变量中,导致要映射的未定义数组。那么,我在这里做错了什么?这是因为组件试图在 GET
请求完成并执行 setDetails(response.data)
之前映射数组,即使它位于代码下方?
function Results()
const location = useLocation();
const history = useHistory();
const [query, setQuery] = useState(location.state.search);
const [details, setDetails] = useState([]);
axios.get("http://localhost:5000/results/" + query).then((response) =>
setDetails(response.data);
console.log(response.data);
);
const results = details.total_results;
const pages = details.total_pages;
const baseURL = "https://image.tmdb.org/t/p/w154";
return (
<Container>
<Card sx= padding: 3, margin: 2 >
<CardContent>
<Grid container>
<Grid item xs=12>
<Typography variant="h5">Results</Typography>
<Typography>results ? results : 0 results found</Typography>
</Grid>
<Grid item xs=12>
<List sx= mt: 5 >
details.results.map((result) =>
return (
<ResultItem
key=result.id
imgURL=baseURL + result.poster_path
title=result.title
year=result.release_date
director=""
synopsis=result.overview
/>
);
)
</List>
</Grid>
</Grid>
</CardContent>
<Pagination
count=pages
onChange=(event, page) =>
history.push("/results" + query + "&page=" + page);
setQuery(query + "&page=" + page);
/>
</Card>
</Container>
);
export default Results;
第二个问题:
我不确定具体原因,但GET
请求触发了来自外部 API 的两个响应,而不仅仅是一个。前端和后端都两次记录检索到的数据,我怀疑多个请求来自我的前端,导致后端也触发多个请求。当我的代码中的某些内容触发无限循环的请求时,这与之前的错误相比是一个巨大的进步。
我想我以后可能也会遇到分页问题,但那是另一回事了。
【问题讨论】:
【参考方案1】:问题一
初始details
状态是一个数组,而不是具有results
数组属性的对象。
const [details, setDetails] = useState([]);
因此尝试映射 details.results
会导致错误“无法读取未定义的属性 X。
要解决此问题,请使用与以后使用方式相匹配的有效初始 details
状态。它应该是一个具有有效results
数组属性的对象。
const [details, setDetails] = useState( results: [] );
问题二
您正在函数组件的主体中调用 axios 请求,这是一种无意的副作用。这可能是由于将您的应用程序渲染为 React.StrictMode
组件,该组件双重调用某些生命周期方法和函数,作为 detect unexpected side-effects 的一种方式,函数体就是其中之一。
您应该将其移动到 useEffect
挂钩中,并将 query
作为依赖项。
useEffect(() =>
axios.get("http://localhost:5000/results/" + query)
.then((response) =>
setDetails(response.data);
);
, [query]);
【讨论】:
以上是关于TypeError:无法读取未定义的属性(读取“地图”),以及 React.js 中的多个 API 请求的主要内容,如果未能解决你的问题,请参考以下文章
未处理的拒绝(TypeError):无法读取反应中未定义的属性“setState”(firestore)
如何使用自定义错误消息捕获“TypeError:无法读取未定义的属性(读取'0')”?