简体   繁体   中英

React useEffect stop infinite loop

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM