This code makes an infinite loop, I need to find a way to fix it.
I want to fill the state moviesinfos with moviesData values to be able to map on it to display cards for each movie.
First, I have tried to setMovieinfos just after the push function but it did not work. So I thought that it would be nicer to put it into an independant useEffect.
It doesn't seems to be the right way to do that ^^.
function App() {
const [movieid, setMovieid] = useState([]);
const [movieinfos, setMovieinfos] = useState([]);
let moviesData = []
useEffect(() => {
axios.get('http://localhost:5000')
.then(function (response) {
// handle success
console.log(response.data.movies)
setMovieid(response.data.movies)
})
.catch(function (error) {
// handle error
console.log(error);
})
}, []);
console.log(movieid)
useEffect(() => {
for (const movie of movieid) {
console.log(movie.movieid)
axios.get(`${BASE_URL}${movie.movieid}?api_key=${API_KEY}&language=fr`)
.then(function (response) {
// handle success
moviesData.push(
{Genres: response.data.genres,
Overview: response.data.overview,
Poster: response.data.poster_path,
Company: response.data.production_companies,
Release: response.data.release_date,
Title: response.data.title}
);
})
.catch(function (error) {
// handle error
console.log(error);
})
}
}, [movieid]);
useEffect(() => {
setMovieinfos (moviesData)
}, [moviesData]);
return (
<div className="App">
<div className="Header">
<Logo />
</div>
<div className="Menu">
<Search />
<Add_movie_button />
<Delete_movie_button />
<Random_movie_button />
</div>
<div className="Movies">
{movieinfos.map((movie) => <Movie_card key={movie.Title} data={movie}/>)}
</div>
</div>
);
}
export default App;
As Yohsi pointed out, the infinte loop is caused by that useEffect depending on a new array on every rerender.
My advice though is that you should try to keep your components with as least state as posible.
If you don't need to show the movieid
anywhere, don't set it in a state to be handled by a useEffect later, that just makes it hard to follow.
It looks as if your whole component only would need moviesInfo
state, where you can handle it in a single useEffect:
const [movieinfos, setMovieinfos] = useState([]);
useEffect(() => {
axios
.get("http://localhost:5000")
.then(function (response) {
const movies = response.data.movies;
return Promise.all(
movies.map((movie) =>
axios.get(
`${BASE_URL}${movie.movieId}?api_key=${API_KEY}&language=fr`
)
)
);
})
.then((responses) => {
setMovieinfos(
responses.map((response) => ({
Genres: response.data.genres,
Overview: response.data.overview,
Poster: response.data.poster_path,
Company: response.data.production_companies,
Release: response.data.release_date,
Title: response.data.title,
}))
);
});
}, []);
I'd recommend so much when working with react to avoid using many useEffect
hooks, specially avoid using them to orchestrate side effects that depend on one another.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.