获取TypeError:moveDetails.map在useEffect中尝试使用useState时不是函数


import { useSelector, useDispatch } from "react-redux";
import { useEffect, useState } from "react";
import request from "../../requests";
import { fetchMovies } from "../../feautures/movies/moviesSlice";
import "./SingleMoviePage.scss";
import Rating from "../../components/UI/Rating/Rating";
import axios from "axios";
const SingleMoviePage = ({ match }) => {
const dispatch = useDispatch();
const [movieDetails, setMovieDetails] = useState({})
/*  params */
const movieId = match.params.id;
const page = match.params.page;
const genre = match.params.genre;
/* movies reducer handle */
const movies = useSelector((state) => state.movies.movies);
const moviesStatus = useSelector((state) => state.movies.status);
/* movieDetails reducer handle */

/* base urls */
const baseImgUrl = "https://image.tmdb.org/t/p/original";
const movieDetailUrl = `https://api.themoviedb.org/3/movie/${movieId}?api_key=c057c067b76238e7a64d3ba8de37076e&language=en-US`;


useEffect(() => {
const fetchData = async() => {
let response = await axios.get(movieDetailUrl);
response = response.data;
setMovieDetails(response)
}
fetchData()
},[movieDetailUrl])
console.log("data: ",movieDetails )


let content;
if (moviesStatus === "loading") {
<div>Loading ...</div>;
} else if (moviesStatus === "succeeced") {
let movie = movies.find((movie) => movie.id.toString() === movieId);
content = (
<div
className="single-movie__container"
style={{
backgroundImage: `url(${
movie.backdrop_path
? baseImgUrl + movie.backdrop_path
: baseImgUrl + movie.poster_path
})`,
}}
>
<div className="single-movie__information">
<h1 className="single-movie__title">{movie.title}</h1>
<div className="single-movie__rate">
<Rating
rating={movie.vote_average}
className="single-movie__stars"
/>
<div className="single-movie__average">
{movie.vote_average}(Imdb)
</div>
</div>
<p className="single-movie__overview">{movie.overview}</p>
<p className="single-movie__genres">
<label>Genres</label>
{
movieDetails.genres.map(genre => {
console.log("genre: ",genre)
return(
<div>{genre.name}</div>
)
})
}
</p>
</div>
</div>
);
}
useEffect(() => {
if (genre === "POPULAR") {
dispatch(fetchMovies(request.fetchPopular(page)));
} else if (genre === "NOW PLAYING") {
dispatch(fetchMovies(request.fetchNowPlaying(page)));
} else if (genre === "UP COMING") {
dispatch(fetchMovies(request.fetchUpComing(page)));
}
}, [dispatch, genre, page]);
return <div className="single-movie">{content}</div>;
};
export default SingleMoviePage;

我正在尝试制作一个带有react redu的电影网站。问题是,当我尝试使用useEffect获取电影详细信息,并尝试在中使用map

<p className="single-movie__genres">

我得到TypeError: Cannot read property 'map' of undefined错误,并且使用console.log("data: ", movieDetails)得到空对象(data: {}(。

但如果我刷新页面,一切都很好数据:

{
adult: false, 
backdrop_path: "/6MKr3KgOLmzOP6MSuZERO41Lpkt.jpg",
...
}

使用CCD_ 6。为什么第一次加载页面时无法获取数据?

这是因为您的初始状态不包含"流派";数组。当react试图处理时

movieDetails.genres.map(...)

它之所以失败,是因为movieDetails.gents是未定义的(当然,undefined不支持map方法(。在初始状态中包括空数组,如:

const [movieDetails, setMovieDetails] = useState({genres:[]})

或者使用"你链中的运营商类似:

movieDetails.genres?.map(...)
map方法是类型数组的原型函数。当使用useState钩子设置默认值时,应该像这样将moviedetails声明为数组。
const [movieDetails, setMovieDetails] = useState([])

有一点我不明白。据我所知,当组件第一次加载时,useEffect工作了,并在映射函数工作后用数据填充了我的movieDetails。我的意思是js从上到下工作movieStatus不应该在映射函数之前填充数据吗?

最新更新