简体   繁体   English

尝试使用 React useState 更改鼓机上的声音库,但更改库功能运行两次

[英]Trying to use React useState to change Sound Banks on a Drum Machine but changing banks function is running twice

I'm creating a drum machine using React.我正在使用 React 创建一个鼓机。 So far I've gotten everything to work, but now that I've tried implementing a second sound bank I've run into some problems with the event listeners.到目前为止,我已经完成了所有工作,但是现在我已经尝试实现第二个声音库,但在事件侦听器方面遇到了一些问题。

So far, changing banks using handleclick works absolutely fine.到目前为止,使用 handleclick 更改银行非常有效。 However, when I use event listeners for some reason both bank1 and bank2 audios are playing over the top ofeach other.但是,当我出于某种原因使用事件侦听器时,bank1 和 bank2 音频都在彼此之上播放。

I have no idea where I'm going wrong with my logic.我不知道我的逻辑哪里出了问题。

Any help would be greatly appreciated任何帮助将不胜感激

Here's my code so far (apologies for messy code).到目前为止,这是我的代码(对凌乱的代码表示歉意)。

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

const audioSamples = {
  bank1:{
  q: new Audio("http://dight310.byu.edu/media/audio/FreeLoops.com/3/3/Free%20Kick%20Sample%208-900-Free-Loops.com.mp3"),
  w: new Audio("http://www.denhaku.com/r_box/sr16/sr16sd/alloysnr.wav"),
  e: new Audio("http://dight310.byu.edu/media/audio/FreeLoops.com/5/5/Long%20Open%20Hi%20Hat%20002-1653-Free-Loops.com.mp3"),
  a: new Audio("http://dight310.byu.edu/media/audio/FreeLoops.com/4/4/Korg%20Ride%20Cymbal%202-2526-Free-Loops.com.mp3"),
  s: new Audio("http://electrongate.com/dmxfiles/DXCRASH.wav"),
  d: new Audio("http://cd.textfiles.com/10000soundssongs/WAV/COWBELL1.WAV")
  },
  bank2:{
    q: new Audio("http://cd.textfiles.com/10000soundssongs/WAV/EERIE_1.WAV"),
    w: new Audio("http://www.denhaku.com/r_box/linn/congal.wav"),
    e: new Audio("http://electrongate.com/dmxfiles/conga.wav"),
    a: new Audio("http://dight310.byu.edu/media/audio/FreeLoops.com/4/4/Korg%20Ride%20Cymbal%202-2526-Free-Loops.com.mp3"),
    s: new Audio("http://electrongate.com/dmxfiles/DXCRASH.wav"),
    d: new Audio("http://cd.textfiles.com/10000soundssongs/WAV/COWBELL1.WAV")
    }
}
   
function App() {

  const [banknum, setBanknum] = useState(1); 
 
  function changeBank() {
    setBanknum(prevBanknum => prevBanknum === 1 ? prevBanknum = 2 : prevBanknum = 1) 
  }
  console.log(banknum)
  document.addEventListener('keydown', function(e) {
 
    if(banknum === 1 && audioSamples.bank1[e.key] ){
      audioSamples.bank1[e.key].load()
      audioSamples.bank1[e.key].play()
      }
      else if (banknum === 2 && audioSamples.bank1[e.key]) {
      audioSamples.bank2[e.key].load()
      audioSamples.bank2[e.key].play()
     }
      console.log(banknum)
      }
   
    )

  

  function handleClick(e) {
    if(banknum === 1){
    audioSamples.bank1[e.target.id].play()
    }
    else if (banknum === 2) {audioSamples.bank2[e.target.id].play() }
    }

  return (
    <div id="DrumMachine" className="App" >
      <button id="q" onClick={handleClick} >Q</button>
      <button id="w" onClick={handleClick}>W</button>
      <button id="e" onClick={handleClick}>E</button>
      <button id="a" onClick={handleClick}>A</button>
      <button id="s" onClick={handleClick}>S</button>
      <button id="d" onClick={handleClick}>D</button>
      <button id ="banks" onClick={changeBank}>Change Bank
      </button>
    </div>
  );
}
export default App;

AddEventListener is rendering twice in your case. AddEventListener 在您的情况下呈现两次。

Do this instead.改为这样做。

  const handleEvent = useCallback((e) => {
    if (banknum === 1 && audioSamples.bank1[e.key]) {
      audioSamples.bank1[e.key].load();
      audioSamples.bank1[e.key].play();
    } else if (banknum === 2 && audioSamples.bank2[e.key]) {
      audioSamples.bank2[e.key].load();
      audioSamples.bank2[e.key].play();
    }
  }, [banknum])

  useEffect(() => {
    document.addEventListener("keydown", handleEvent);
    return () => {
      document.removeEventListener("keydown", handleEvent);
    }
  }, [banknum, handleEvent]);

Working sandbox here . 在这里工作沙箱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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