Filter response from api on user search getting error :`Unhandled Rejection (TypeError): Cannot read property 'results' of undefined`
Filter response from api on user search getting error :`Unhandled Rejection (TypeError): Cannot read property 'results' of undefined`
正在尝试使用过滤后的 api 响应更新我的状态。我拨打电话,然后更新 results
状态(见下文)。
api 通话
async searchMovies(keyword, year) {
const response = await getMoviesFiltered(keyword, year);
console.log(response); // filtered response
this.setState({ results: response.results});
}
请求
export const getMoviesFiltered = async (keyword, year) => {
try {
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=<apikey>&language=en-US&query=${keyword}&page=1&include_adult=false&year=${year}`
);
console.log(response.data.results);
return response.data;
} catch (error) {
console.error(error);
}
};
来自api的回复:
{page: 1, results: Array(20), total_pages: 95, total_results: 1889}
page: 1
results: (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
total_pages: 95
total_results: 1889
我想用响应(结果键,它是一个数组)更新我的状态并映射它,但它告诉我 Unhandled Rejection (TypeError): Cannot read property 'results' of undefined
这很奇怪,因为我可以在响应
中看到 results
此外,当我尝试更新 response
状态下的结果时,例如
this.setState({ results: response});
我得到:
TypeError: movies.map is not a function
即它无法映射我传递的响应....
我查看了堆栈上的其他问题,他们说这是因为响应不是数组,但我的是 :S
这里是我映射数据的地方,它是从父级传递下来的。
<MovieList movies={results || []} genres={genreOptions || []} />
组件:
return (
<MoviesWrapper>
{movies && movies.map((movie, index) => {
const {
title,
vote_average,
overview,
release_date,
poster_path,
genre_ids,
} = movie;
return (
<MovieItem
key={index}
title={title}
rating={vote_average}
overview={overview}
release={release_date}
poster={poster_path}
movieGenres={matchGenres(genre_ids)}
/>
);
})}
谁能看出哪里出了问题?
看不到你的完整组件代码;但问题可能是您将状态初始化为 null。
当您在代码中定义状态时,状态会使用其初始值进行初始化。
const [Movies, setMovies] = useState(null)
现在我已经定义了一个名为 Movies 的状态,它的开头为 null。
我在 useEffect 块(或 ComponentDidMount)进行 API 调用;在我的 API 响应之后,我将状态更新为使用 setState 响应,或者在上面的示例中; setMovies().
useEffect(() => {
const response = await axios.get(`ENDPOINT_URL`);
setMovies(response)
},[]);
现在我的状态是来自 API 调用的响应数组。只有现在我可以使用地图功能,以前不能;因为它为 null 并且会引发错误。
让我们深入探讨 React 如何在 return 块中处理此流程。 React 不会等待 API 调用结束来初始化状态并打印 return 块中的内容。这个很重要;因为如果我尝试在第一次渲染时对状态做些什么;在 React 使用来自 api 的响应数组更新状态之前;状态将为“空”。
所以顺序是这样的
1.Initialize 初始值状态(空)
2.Renderreturn块
3.Update 状态(示例:setMovies([1,2,3]))
4.Re-渲染return块。
假设我的 return 块中有 {console.log(电影)}。我将在控制台中看到 2 个日志;第一个会说“null”(第 2 步),第二个会说“[1,2,3]”(第 4 步)
现在,如果我在 return 块中有 Movies.map 函数;它会抛出一个错误,说“TypeError: Movies.map is not a function”;因为 Movies 一开始是 null。
至于你的另一个问题:“未处理的拒绝(TypeError):无法读取未定义的 属性 'results'”
父对象为空时抛出该错误;在这种情况下;结果的父对象。无法确定是哪个“结果”在此处引发错误,因为您没有提供确切错误的行号。例如; data.results 正在扔这个;这意味着“数据”是空的并且没有作为子对象的结果。这很可能是两件事的结果;当我们判断响应对象模式错误时,(例如:response.data.movies.results 而不是 response.data.results)或者我们试图在填充它之前达到 data.results “例如:data = apiresponse.content ".
如果你能提供一个CodeSandbox;回答起来会容易得多。
在codesandbox之后编辑
更正错误:https://codesandbox.io/s/movies-app-angela-forked-ehr9u
错误:
MovieList .map 电影;由于我上面解释的原因,状态初始化为空;所以它会抛出错误;您只需在地图函数上方添加 {movies && movies.length > 0 ...} 1 步即可检查电影是否存在且不为空。
在您的 searchMovies 函数中,您的 fetcher 调用会捕获
错误,但只有 console.logs;这会在 searchMovies 中产生问题
功能。因为即使响应为 null 或 errorcode,searchMovies 函数仍然继续工作,并错误地更新状态。
您的搜索没有在视图中显示响应;因为
在 searchMovies 中调用之后;您需要提供对结果对象数组的直接访问,以便视图知道类型。 MoviesList 组件知道并呈现电影对象数组;但是在搜索之后,您将状态设置为也包含不同属性的对象;所以 MoviesList 不知道如何呈现结果。不久; response.data.results 而不是 response.data.
您的 searchBar 组件,它实际上并不搜索确切的按键,而是搜索之前的 1 个。就像您尝试搜索“黑暗”一样;它搜索“dar”。当您搜索“d”时,它会搜索空字符串。您必须输入“dark”加 1 space 才能实际搜索“dark”。因此,api returns 422 在您键入的第一个字符出现无法处理的输入错误,因为它试图搜索空字符串。这是因为你更新状态,然后调用搜索api。但是更新状态是异步的,在将状态发送到 api fetcher 函数之前状态更新不会完成。如此简单的解决方案就是发送搜索获取器函数 event.target.value,而不是您正在更新的状态。
一个小提醒:现在更改您的 API 密钥;因为它暴露在网络上。
问题已解决。
这与 searchMovies
api 调用有关,当我返回 api 响应时,我必须首先检查是否确实有响应全部。如果有响应,那么我想访问该响应中的 results
数组。
基本上在设置状态时这样做:
this.setState({ results: response && response.results });
而不是:
this.setState({ results: response.results });
正在尝试使用过滤后的 api 响应更新我的状态。我拨打电话,然后更新 results
状态(见下文)。
api 通话
async searchMovies(keyword, year) {
const response = await getMoviesFiltered(keyword, year);
console.log(response); // filtered response
this.setState({ results: response.results});
}
请求
export const getMoviesFiltered = async (keyword, year) => {
try {
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=<apikey>&language=en-US&query=${keyword}&page=1&include_adult=false&year=${year}`
);
console.log(response.data.results);
return response.data;
} catch (error) {
console.error(error);
}
};
来自api的回复:
{page: 1, results: Array(20), total_pages: 95, total_results: 1889}
page: 1
results: (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
total_pages: 95
total_results: 1889
我想用响应(结果键,它是一个数组)更新我的状态并映射它,但它告诉我 Unhandled Rejection (TypeError): Cannot read property 'results' of undefined
这很奇怪,因为我可以在响应
results
此外,当我尝试更新 response
状态下的结果时,例如
this.setState({ results: response});
我得到:
TypeError: movies.map is not a function
即它无法映射我传递的响应.... 我查看了堆栈上的其他问题,他们说这是因为响应不是数组,但我的是 :S
这里是我映射数据的地方,它是从父级传递下来的。
<MovieList movies={results || []} genres={genreOptions || []} />
组件:
return (
<MoviesWrapper>
{movies && movies.map((movie, index) => {
const {
title,
vote_average,
overview,
release_date,
poster_path,
genre_ids,
} = movie;
return (
<MovieItem
key={index}
title={title}
rating={vote_average}
overview={overview}
release={release_date}
poster={poster_path}
movieGenres={matchGenres(genre_ids)}
/>
);
})}
谁能看出哪里出了问题?
看不到你的完整组件代码;但问题可能是您将状态初始化为 null。
当您在代码中定义状态时,状态会使用其初始值进行初始化。
const [Movies, setMovies] = useState(null)
现在我已经定义了一个名为 Movies 的状态,它的开头为 null。
我在 useEffect 块(或 ComponentDidMount)进行 API 调用;在我的 API 响应之后,我将状态更新为使用 setState 响应,或者在上面的示例中; setMovies().
useEffect(() => {
const response = await axios.get(`ENDPOINT_URL`);
setMovies(response)
},[]);
现在我的状态是来自 API 调用的响应数组。只有现在我可以使用地图功能,以前不能;因为它为 null 并且会引发错误。
让我们深入探讨 React 如何在 return 块中处理此流程。 React 不会等待 API 调用结束来初始化状态并打印 return 块中的内容。这个很重要;因为如果我尝试在第一次渲染时对状态做些什么;在 React 使用来自 api 的响应数组更新状态之前;状态将为“空”。
所以顺序是这样的
1.Initialize 初始值状态(空)
2.Renderreturn块
3.Update 状态(示例:setMovies([1,2,3]))
4.Re-渲染return块。
假设我的 return 块中有 {console.log(电影)}。我将在控制台中看到 2 个日志;第一个会说“null”(第 2 步),第二个会说“[1,2,3]”(第 4 步)
现在,如果我在 return 块中有 Movies.map 函数;它会抛出一个错误,说“TypeError: Movies.map is not a function”;因为 Movies 一开始是 null。
至于你的另一个问题:“未处理的拒绝(TypeError):无法读取未定义的 属性 'results'”
父对象为空时抛出该错误;在这种情况下;结果的父对象。无法确定是哪个“结果”在此处引发错误,因为您没有提供确切错误的行号。例如; data.results 正在扔这个;这意味着“数据”是空的并且没有作为子对象的结果。这很可能是两件事的结果;当我们判断响应对象模式错误时,(例如:response.data.movies.results 而不是 response.data.results)或者我们试图在填充它之前达到 data.results “例如:data = apiresponse.content ".
如果你能提供一个CodeSandbox;回答起来会容易得多。
在codesandbox之后编辑
更正错误:https://codesandbox.io/s/movies-app-angela-forked-ehr9u
错误:
MovieList .map 电影;由于我上面解释的原因,状态初始化为空;所以它会抛出错误;您只需在地图函数上方添加 {movies && movies.length > 0 ...} 1 步即可检查电影是否存在且不为空。
在您的 searchMovies 函数中,您的 fetcher 调用会捕获 错误,但只有 console.logs;这会在 searchMovies 中产生问题 功能。因为即使响应为 null 或 errorcode,searchMovies 函数仍然继续工作,并错误地更新状态。
您的搜索没有在视图中显示响应;因为 在 searchMovies 中调用之后;您需要提供对结果对象数组的直接访问,以便视图知道类型。 MoviesList 组件知道并呈现电影对象数组;但是在搜索之后,您将状态设置为也包含不同属性的对象;所以 MoviesList 不知道如何呈现结果。不久; response.data.results 而不是 response.data.
您的 searchBar 组件,它实际上并不搜索确切的按键,而是搜索之前的 1 个。就像您尝试搜索“黑暗”一样;它搜索“dar”。当您搜索“d”时,它会搜索空字符串。您必须输入“dark”加 1 space 才能实际搜索“dark”。因此,api returns 422 在您键入的第一个字符出现无法处理的输入错误,因为它试图搜索空字符串。这是因为你更新状态,然后调用搜索api。但是更新状态是异步的,在将状态发送到 api fetcher 函数之前状态更新不会完成。如此简单的解决方案就是发送搜索获取器函数 event.target.value,而不是您正在更新的状态。
一个小提醒:现在更改您的 API 密钥;因为它暴露在网络上。
问题已解决。
这与 searchMovies
api 调用有关,当我返回 api 响应时,我必须首先检查是否确实有响应全部。如果有响应,那么我想访问该响应中的 results
数组。
基本上在设置状态时这样做:
this.setState({ results: response && response.results });
而不是:
this.setState({ results: response.results });