Home > database >  The 2 useEffect() hooks that i used in my drummachine are clustering
The 2 useEffect() hooks that i used in my drummachine are clustering

Time:08-17

Wrote my drum-machine code and it perfectly works using mouse as i toggle from drumpad A-B, but on using useEffect() hooks to make it react to keypress separately, they clutter each other. When i switch from drum kick to piano for example and i press the keypad, the sound from drum kick buttons plays together with piano buttons and vice-versa... please how do i solve this? here is the code

    
   const arrBank1 = useSelector((state)=>state.playNow.map(loop=>loop));
   const arrPiano = useSelector((state)=>state.playPiano.map(loop=>loop));
   const [switchOn, switchOff] = useState(false);
   const [bank, setBank] = useState(false);

   //const [play, setPlay] = useState(true);

    useEffect(()=>{
        if(bank===false ){
            document.addEventListener("keydown", (event)=>{
            
                arrBank1.map(keys2=>{
                    for(let i = 0; i<keys2["id"].length; i  ){
                        if((event.key.toUpperCase()=== keys2["value"][i])){     
                            handlePlay(event.key.toUpperCase(),keys2["id"]);   
                        }
                    }
                })
            })   
        }
   })   

    useEffect(()=>{
        if(bank===true){
            document.addEventListener("keydown", (event)=>{
                
                arrPiano.map(keys=>{
                    for(let i = 0; i<keys["id"].length; i  ){
                        if((event.key.toUpperCase() === keys["value"][i])){                 
                            handlePlay(keys["id"],keys["id"]);
                        }
                    }
                }) 
                
            }) 
        }
            
    })

    //This function changes or handles the bank switch toggle from drum kicks to piano
    const handleBankSwitch = () =>{
        setBank(!bank);
            if(bank===false){
                document.getElementById("bank1But").style.display="none";
                document.getElementById("bank2But").style.display="grid";
            }else{
                document.getElementById("bank1But").style.display="grid";
                document.getElementById("bank2But").style.display="none";
            }
    }
   //This function handles the playing of the audios
    const handlePlay = (playId,showId) =>{
        if(switchOn === true){
            //document.getElementById(playId).duration=1;
            document.getElementById(playId).play();
            document.getElementById("display").innerText= showId;
        }       
    }
   //This function handles the display of the switch toggle
    const handleSwitch=()=>{
        switchOn===true?document.getElementById("switch").innerText = "OFF":
        document.getElementById("switch").innerText = "ON";
    }

    return(
        
        <Container fluid className='bigContainer'>
            <div className="drum-container">
                <div className='bothButtons' id="bank1But" >
                    {arrBank1.map(i=>{
                        return <div key={i.value}>
                            <Button id='button1' className="button"  onClick={()=>handlePlay(i.value,i.id)} >{i.value}</Button>
                            <audio src={i.url} id={i.value}></audio>
                        </div> 
                    })}
                </div>
                
               <div className='bothButtons' id="bank2But" style={{display:"none"}}>
                    {arrPiano.map(j=>{
                        return <div key={j.url}>
                            <Button id='button2' className="buttons"  onClick={()=>handlePlay(j.id,j.id)} >{j.value}</Button>
                            <audio src={j.url} id={j.id}></audio>
                        </div> 
                    })}
                </div>`enter code here```

CodePudding user response:

You are attaching event listeners to window, but never removing them. This means when you switch to the drum kit, the piano event listeners will still be attached, and vice versa. You need to remove the previously attached event listeners before adding new ones.

I also noticed that your effects don't specify dependency arrays. This means they will run, and thus attach event listeners, on every render. You should only change the event listeners when bank changes - you can achieve this by adding a dependency array to your useEffect.

  • Related