Home > Net >  React Hook useEffect has a missing dependency. What's the solution?
React Hook useEffect has a missing dependency. What's the solution?

Time:11-11

I'm just about finished with a project but I'm getting these two errors. Does anyone know how I can fix this?

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

src\components\MusicPlayer.jsx Line 48:9: React Hook useEffect has a missing dependency: 'togglePlay'. Either include it or remove the dependency array react-hooks/exhaustive-deps

Any help is greatly appreciated!

function App() {


//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=&language=en-US&page=1';
const kidsMovieURL = 'https://api.themoviedb.org/3/discover/movie?api_key=&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 kidsAnimatedMovies = 'https://api.themoviedb.org/3/discover/movie?api_key=1f7c961ae4f02a23e0968d449c15bc98&with_genres=16';
const kidsSeries = 'https://api.themoviedb.org/3/discover/tv?api_key=&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);

}, [])

const [songClicked, setSongClicked] = useState({})

import React, { useState, useEffect, useRef } from 'react'



function MusicPlayer({songs}) {

      //Test 
const songFiles = songs.map(song => song.songFile)

    //Hooks
    const audioPlayer = useRef()

    //State
    const [index, setIndex] = useState(0);
    const { songClicked} = useContext(songContext)
    // setSongClicked
    const [currentSong, setCurrentSong] = useState(songClicked);
    const [isPlaying, setisPlaying] = useState(false);
    const [volume, setVolume] = useState(30);
    const [mute, setMute] = useState(false);


     useEffect(() => {
        setCurrentSong(songClicked)
        
         if (songClicked) {
             audioPlayer.current.play()
         }
        
         if (songClicked) {
             togglePlay()
         }

     }, [songClicked])
 

    useEffect(() => {
        if(audioPlayer) {
            audioPlayer.current.volume = volume / 100;
        }
    }, [volume]);


    function togglePlay() {
        if(!isPlaying) {
            audioPlayer.current.play()
        } else {
            audioPlayer.current.pause()
        }
        // setisPlaying(prev => !prev)
        setisPlaying(isPlaying => !isPlaying)
    }

    function toggleSkipForward() {
        if(index >= songFiles.length - 1) {
            setIndex(0);
            audioPlayer.current.src = songFiles[0];
            audioPlayer.current.play();
        } else {
            setIndex(prev => prev   1);
            audioPlayer.current.src = songFiles[index   1];
            audioPlayer.current.play();
        }
    }


    function toggleSkipBackward() {
        if(index > 0) {
            setIndex(prev => prev -1);
            audioPlayer.current.src = songFiles[index -1];
            audioPlayer.current.play();
        } 
    }
    
    

    function VolumeBtns() {
        return mute
            ? <VolumeOffIcon sx={{color: 'lime', '&:hover': {color: 'white'}}} onClick={() => setMute(!mute)} />
            : volume <= 20 ? <VolumeMuteIcon sx={{color: 'lime', '&:hover': {color: 'white'}}} onClick={() => setMute(!mute)} />
            : volume <= 75 ? <VolumeDownIcon sx={{color: 'lime', '&:hover': {color: 'white'}}} onClick={() => setMute(!mute)} />
            : <VolumeUpIcon sx={{color: 'lime', '&:hover': {color: 'white'}}} onClick={() => setMute(!mute)} />
            }



  return (


    <div className='music-player-container'>

    <audio src={currentSong} ref={audioPlayer} muted={mute} webkit-playsinline="true" playsInline="true" autoplay="" />   

        <div className="controls">

            <div className="volume">

                <IconButton>
                    <VolumeBtns />
                </IconButton>

                 <Slider min={0} max={100} value={volume} onChange={(e,v) => setVolume(v)}
                defaultValue={50}
                    sx={{
                    width: 100,
                    color: 'success.main',
                    margin: '20px',
                    }} /> 
            </div>

            <div className="control-panel">

                    <IconButton onClick={toggleSkipBackward}>
                        <SkipPreviousIcon
                        sx={{
                            margin: '10px',
                            cursor: 'pointer',
                            color: 'silver', '&:hover': {color: 'blue'}
                        }} />
                    </IconButton>

                    {/* Play/Pause */}
                
                {!isPlaying
                  ?  <IconButton onClick={togglePlay}>
                        <PlayArrowIcon sx={{ margin: '10px', cursor: 'pointer', color: 'silver', '&:hover': {color: 'blue'} }} />
                    </IconButton>
                    
                   : <IconButton onClick={togglePlay}>
                        <PauseIcon sx={{ margin: '10px', cursor: 'pointer', color: 'silver', '&:hover': {color: 'blue'} }} />
                    </IconButton>
                }
                    
                    {/* Play/Pause */}


                    <IconButton onClick={toggleSkipForward}>
                        <SkipNextIcon
                        sx={{
                            margin: '10px',
                            cursor: 'pointer',
                            color: 'silver', '&:hover': {color: 'blue'}
                        }} />
                    </IconButton>

            </div>
        </div>
                         
            
    </div>


  )
}

export default MusicPlayer

CodePudding user response:

For the first error, If you're not using the function elsewhere, you can define your getMoviesData() function within the useEffect and then call it.

useEffect(() => {
    const getMoviesData = async function (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:

You need to use useCallback hook in this instance.

const getMoviesData = useCallback(async (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))
},[])

and in useEffect hook

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