Home > Software design >  React Hook useEffect has a missing dependency. How do I fix this error?
React Hook useEffect has a missing dependency. How do I fix this error?

Time:11-09

React Hook useEffect has a missing dependency.

Line 92:4: React Hook useEffect has a missing dependency: 'getMoviesData'. Either include it or remove the dependency array react-hooks/exhaustive-deps

Can someone tell me how to fix this error? I'm sure it's something very simple but any help would be greatly appreciated!

function App() {

// * MOVIE API *


//State 
const [movies, setMovies] = useState([])
const [topMovies, setTopMovies] = useState([])
const [kidsMovies, setKidsMovies] = useState([])
const [setKidsTv] = useState([])
//kidsTv
const [setTvShows] = useState([])
//TvShows
const [kidsTvSeries, setKidsTvSeries] = useState([])




//API URL 
const url = 'https://api.themoviedb.org/3/discover/movie?api_key=&with_genres=28/';
const tvUrl = 'https://api.themoviedb.org/3/tv/popular?api_key=8&language=en-US&page=1';
const kidsMovieURL = 'https://api.themoviedb.org/3/discover/movie?api_key=8&certification_country=US&certification.lte=G&with_genres=16&include_adult=false&sort_by=popularity.desc';
const kidsTvURL = 'https://api.themoviedb.org/3/tv/popular?api_key=8&language=en-US&page=1&with_genres=16&include_adult=false&sort_by=popularity.desc';
const topPicks = 'https://api.themoviedb.org/3/movie/top_rated?api_key=&language=en-US&page=1';
const kidsSeries = 'https://api.themoviedb.org/3/discover/tv?api_key=1f7c961ae4f02a23e0968d449c15bc98&with_genres=10762'

//Async function to fetch API
async function getMoviesData (url, tvUrl, topPicks, kidsMovieURL, kidsTvUrl, kidsSeries) {

  await fetch(url).then(res => res.json()).then(data => setMovies(data.results))
  await fetch(topPicks).then(res => res.json()).then(data => setTopMovies(data.results))
  await fetch(tvUrl).then(res => res.json()).then(data => setTvShows(data.results))
  await fetch(kidsMovieURL).then(res => res.json()).then(data => setKidsMovies(data.results))
  await fetch(kidsTvUrl).then(res => res.json()).then(data => setKidsTv(data.results))
  await fetch(kidsSeries).then(res => res.json()).then(data => setKidsTvSeries(data.results))
}



//Use Effect 
 useEffect(() => { 
  getMoviesData(url, tvUrl, topPicks, kidsMovieURL, kidsTvURL, kidsSeries);

}, [])


  return (

    <div className='app'>

      <div className="header">
        <Header Home={Home} Movies={Movies} Kids={Kids} Music={lazyMusic} movies={movies} topMovies={topMovies} kidsMovies={kidsMovies} kidsTvSeries={kidsTvSeries} />
      </div>

      <div className="music-player">
        <MusicPlayer />
      </div>
  

    </div>
  )
}

export default App

CodePudding user response:

Mayve you could try something like that (using useCallback):

const getMoviesData = useCallback(() => { /* your code */ }, []);

CodePudding user response:

You just have to add the getMoviesData to the dependency array of the useEffect.

  const getMoviesData = useCallback(async () => {
    await fetch(url).then(res => res.json()).then(data => setMovies(data.results))
    await fetch(topPicks).then(res => res.json()).then(data => setTopMovies(data.results))
    await fetch(tvUrl).then(res => res.json()).then(data => setTvShows(data.results))
    await fetch(kidsMovieURL).then(res => res.json()).then(data => setKidsMovies(data.results))
    await fetch(kidsTvUrl).then(res => res.json()).then(data => setKidsTv(data.results))
    await fetch(kidsSeries).then(res => res.json()).then(data => setKidsTvSeries(data.results))
    }, [])

    useEffect(() => { 
      getMoviesData(url, tvUrl, topPicks, kidsMovieURL, kidsTvURL, kidsSeries);
    
    }, [getMoviesData])

CodePudding user response:

You should move getMoviesData func inside callback of useEffect like this:

//Use Effect 

 useEffect(() => { 
//Async function to fetch API
  async function getMoviesData (url, tvUrl, topPicks, kidsMovieURL, kidsTvUrl, kidsSeries) {
   await fetch(url).then(res => res.json()).then(data => setMovies(data.results))
   await fetch(topPicks).then(res => res.json()).then(data => setTopMovies(data.results))
   await fetch(tvUrl).then(res => res.json()).then(data => setTvShows(data.results))
   await fetch(kidsMovieURL).then(res => res.json()).then(data => setKidsMovies(data.results))
   await fetch(kidsTvUrl).then(res => res.json()).then(data => setKidsTv(data.results))
   await fetch(kidsSeries).then(res => res.json()).then(data => setKidsTvSeries(data.results))
  }
  getMoviesData(url, tvUrl, topPicks, kidsMovieURL, kidsTvURL, kidsSeries);

}, [])

CodePudding user response:

When using useEffect, one thing to keep in mind is that any state variable or any function that is used inside the effect function (the 1st argument passed to useEffect) should be included in the dependency array (the 2nd argument).

In your component, you are using the getMoviesData function inside the useEffect hook, but you have not included that in the dependency array. That is why you are getting the linter warning. To fix this, you just have to add the function in the dependency array. So your useEffect hook will become this:

useEffect(() => { 
  getMoviesData(url, tvUrl, topPicks, kidsMovieURL, kidsTvURL, kidsSeries);
}, [getMoviesData])

However, this creates a problem - this means that whenever the getMoviesData function is recreated, the effect will run once again. Since this function is updating the state, it will cause the component to re-render, which will then cause this function to be re-created, which in turn will cause the effect to run again, creating an infinite loop.

To solve this, you have a few options:

  1. Move the getMoviesData inside the useEffect's effect function (if you are not using it outside the useEffect hook)
  2. Move it outside the component (if you are not interacting with state or any other component methods)
  3. Wrap it with useCallback to memoize the function reference.

In your case, you can go with option #1.

useEffect(() => {
  function getMoviesData (url, tvUrl, topPicks, kidsMovieURL, kidsTvUrl, kidsSeries) {
    fetch(url).then(res => res.json()).then(data => setMovies(data.results))
    fetch(topPicks).then(res => res.json()).then(data => setTopMovies(data.results))
    fetch(tvUrl).then(res => res.json()).then(data => setTvShows(data.results))
    fetch(kidsMovieURL).then(res => res.json()).then(data => setKidsMovies(data.results))
    fetch(kidsTvUrl).then(res => res.json()).then(data => setKidsTv(data.results))
    fetch(kidsSeries).then(res => res.json()).then(data => setKidsTvSeries(data.results))
  }

  getMoviesData(url, tvUrl, topPicks, kidsMovieURL, kidsTvURL, kidsSeries);
}, [getMoviesData])
  • Related