为啥我不能用我的 api 响应更新我的状态?数据是一个对象数组
Posted
技术标签:
【中文标题】为啥我不能用我的 api 响应更新我的状态?数据是一个对象数组【英文标题】:why can i not update my state with my api response? data is an array of objects为什么我不能用我的 api 响应更新我的状态?数据是一个对象数组 【发布时间】:2021-04-15 00:46:54 【问题描述】:我有两个返回 JSON 对象的 api 请求。它们返回一个对象数组。
我提出的一个 API 请求很好,允许我使用响应更新状态,但另一个(如下)没有,我不明白为什么。
获取流派列表的 API 请求:
async getGenreList()
const genresResults = await getGenres();
return genresResults;
请求:
export const getGenres = async () =>
try
const response = await axios.get(
"https://api.themoviedb.org/3/genre/movie/list?api_key=<APIKEY>&language=en-US"
);
const genres = response.data;
return genres;
catch (error)
console.error(error);
;
响应是一个包含 19 个流派对象的数组,但这只是一个示例:
[
id: 28, name: "Action",
id: 12, name: "Adventure"
]
然后我想像这样更新state
并将响应传递给genreOptions
。但它告诉我Error: Objects are not valid as a React child (found: object with keys id, name). If you meant to render a collection of children, use an array instead.
componentDidMount()
this.getGenreList().then((response) =>
console.log(response)
this.setState( genreOptions: response);
);
当我更新状态并对其进行映射时,以下内容有效,但我不想这样做,我想向下传递整个响应,以便我可以映射组件中的数据,因为我需要它在那里做一些数据匹配。
this.setState( genreOptions: response.map((genreOption) =>
return genreOption.name
));
这是状态:
this.state =
results: [],
movieDetails: null,
genreOptions: [],
;
我想将这里的genreOptions 传递给genres
,然后在MovieResults
组件中映射它。
<MovieResults>
totalCount > 0 && <TotalCounter>totalCount results</TotalCounter>
<MovieList movies=results || [] genres=genreOptions || [] />
</MovieResults>
为什么我不能?有任何想法吗?我已经为另一个类似的请求做了它:S
更新显示电影成分
export default class MovieList extends React.Component
render()
const movies, genres = this.props;
const testFunction = (movieGenreIds) =>
const matchMovieGenresAndGenreIds = genres.map((genreId) =>
const matchedGenres = movieGenreIds.find((movieGenre) =>
return movieGenre.id === genreId
)
return matchedGenres // this returns the matching objects
)
const result = matchMovieGenresAndGenreIds.filter(Boolean).map((el)=>
return el.name
)
return result
return (
<MoviesWrapper>
movies.map((movie) =>
const
title,
vote_average,
overview,
release_date,
poster_path,
genre_ids
= movie;
return (
<MovieItem
title=title
rating=vote_average
overview=overview
release=release_date
poster=poster_path
movieGenres=testFunction(genre_ids)
/>
);
)
</MoviesWrapper>
);
**** 电影项目组件***
export default class MovieItem extends React.Component
render()
const title, overview, rating, release, poster, movieGenres = this.props;
return (
// The MovieItemWrapper must be linked to the movie details popup
<MovieItemWrapper>
<LeftCont>
<img
className="movie-img"
src=`https://image.tmdb.org/t/p/w500$poster`
/>
</LeftCont>
<RightCont>
<div className="movie-title-container">
<h2 className="movie-title">title</h2>
<Rating>rating</Rating>
</div>
<div>movieGenres</div>
<p>overview</p>
<p>release</p>
</RightCont>
</MovieItemWrapper>
);
【问题讨论】:
看来您的问题出在MovieList
组件中。你能发布它的代码吗?特别是渲染部分。
好的,我会发布,但它有点乱。在MovieList
组件中,我想使用genres
即genreOptions
并将id
的genreOption
与另一个数组中的ID 进行比较 - 用于上下文
别担心,继续。
完成,如果您需要更多关于我在做什么的解释,请告诉我。谢谢!
好吧,我或多或少明白你在做什么,但我很遗憾地告诉你,现在看来问题出在MovieItem
组件内部(我希望你终于试图使用您处理过的数组)。我还看到了其他一些问题,但要完全回答我需要您发布MovieItem
代码。
【参考方案1】:
请按照此步骤修复您的代码。我会试着解释一下一路上发生的事情:
-
在您的主要组件中。将状态设置为您真正想要传递给子组件的值。请记住,
response
将是一个对象数组。
componentDidMount()
this.getGenreList().then((response) =>
this.setState(genreOptions: response);
);
-
在您的
MovieList
组件中。请检查您的testFunction
以尊重数据类型。以下代码将返回一个字符串数组,其中包含电影流派数组中包含的流派名称。
const testFunction = (movieGenreIds) =>
return genres
.filter((genre) =>
return movieGenreIds.includes(genre.id);
)
.map((genre) => genre.name);
;
-
在您的
MovieItem
组件中。 (这才是真正的问题所在)
代替:
<div>movieGenres</div>
你可能想做这样的事情:
<div>movieGenres.join(' ')</div>
这会将您的数组转换为可以呈现的字符串。您的错误是由于您向那里传递了一个 React 无法呈现的对象数组。
如果您有任何疑问,请告诉我。
注意:我建议您使用类型检查器来避免此类问题。并与您的变量命名约定保持一致。
根据聊天中的新信息进行更新:
-
在您的
ExpandableFilters
组件中,您必须修复以下代码以获取流派名称(字符串)。正如聊天中所解释的,您不能将对象作为 JSX 表达式 (
) 的结果,而只能是可以强制转换为字符串、JSX 元素或 JSX 元素数组的原语。
<GenreFilterCont marginTop>
filtersShown && (
<ExpandableFiltersUl>
this.props.movieGenres.map((genre, index) =>
return (
<ExpandableFiltersLi key=index>
<Checkbox />
genre.name
</ExpandableFiltersLi>
);
)
</ExpandableFiltersUl>
)
</GenreFilterCont>
还请注意,我添加了 key
属性。只要有要渲染的元素列表,就应该这样做。有关此的更多信息,我将向您推荐React Docs。
【讨论】:
非常感谢!好的,所以我了解到的是,我实际上能够使用来自 API 请求的响应来更新state
,该请求是一个对象数组,但是我无法从 API 呈现该对象/对象数组作为结果一个 JSX 表达式。在您更正我的代码之前,我在 ExpandableFilters
中渲染了 genre
,这实际上是一个对象,所以它不起作用,它给了我错误 Error: Objects are not valid as a React child (found: object with keys id, name). If you meant to render a collection of children, use an array instead.
以上是关于为啥我不能用我的 api 响应更新我的状态?数据是一个对象数组的主要内容,如果未能解决你的问题,请参考以下文章