TypeError: Cannot read properties of undefined (reading 'map'), and multiple API requests in React.js
TypeError: Cannot read properties of undefined (reading 'map'), and multiple API requests in React.js
我知道这个地图读取错误已经被问过 很多 并且我查看了几个已关闭的问题,但由于它们的原因与我的不同我选择打开一个新话题。目前我面临 2 个错误,所以让我一次解决一个。
我想完成的事情:
提交搜索查询后,应呈现“结果”组件并向我的后端发出 GET
请求(反过来,将向外部发出 GET
请求 API 并将结果发送回 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 的 两个 响应,而不是一个。前端和后端都两次记录检索到的数据,我怀疑多个请求来自我的前端,导致后端也触发多个请求。当我的代码中的某些内容触发请求的无限循环时,这与之前的错误相比迈出了一大步。
我想我以后可能也会遇到分页问题,但那是另一回事了。
第一期
初始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]);
我知道这个地图读取错误已经被问过 很多 并且我查看了几个已关闭的问题,但由于它们的原因与我的不同我选择打开一个新话题。目前我面临 2 个错误,所以让我一次解决一个。
我想完成的事情:
提交搜索查询后,应呈现“结果”组件并向我的后端发出 GET
请求(反过来,将向外部发出 GET
请求 API 并将结果发送回 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 的 两个 响应,而不是一个。前端和后端都两次记录检索到的数据,我怀疑多个请求来自我的前端,导致后端也触发多个请求。当我的代码中的某些内容触发请求的无限循环时,这与之前的错误相比迈出了一大步。
我想我以后可能也会遇到分页问题,但那是另一回事了。
第一期
初始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]);