Cannot execute prop handler in React component

Main question: I cannot execute the local handleClick handler in the code below. Shouldn’t onClick={props.handleClick} work?

Additional info: I would like to move handleClick into the component so I can work to combine the key press and button click events into one method, since they effectively do the same thing. My first step is to be able to connect DrumPad with the handleClick prop from DrumMachine.

let audio = '';
class DrumMachine extends React.Component {
  constructor(props) {
    super(props);
    // local props
    this.state = {
    }
    // bind handlers
    this.handleClick = this.handleClick.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  // handlers
  handleClick() {
    console.log('ding');
  }
  handleKeyPress = (e) => {
    let keyCode = String.fromCharCode(e.keyCode);
    audio = document.getElementById(keyCode);
    audio.currentTime = 0;
    audio.play();
  }
  componentDidMount() {
    document.addEventListener('keydown', this.handleKeyPress);
  }
  componentWillUnmount() {
    document.removeEventListener('keydown', this.handleKeyPress);
  }
  render() {
    return(
      <div id="drum-machine" className="container-fluid">
        <div id="display">
          <DrumPad id="Claves-1" innerText="Q" src="234/234367_736471-lq.mp3" />
          <DrumPad id="Claves-2" innerText="W" src="234/234366_736471-lq.mp3" />
          <DrumPad id="Claves-3" innerText="E" src="234/234365_736471-lq.mp3" />
          <DrumPad id="Tapekick-1" innerText="A" src="211/211422_736471-lq.mp3" />
          <DrumPad id="Tapekick-2" innerText="S" src="211/211420_736471-lq.mp3" />
          <DrumPad id="Tapekick-3" innerText="D" src="211/211418_736471-lq.mp3" />
          <DrumPad id="Tumbadora-1" innerText="Z" src="234/234374_736471-lq.mp3" />
          <DrumPad id="Tumbadora-2" innerText="X" src="234/234375_736471-lq.mp3" />
          <DrumPad id="Tumbadora-3" innerText="C" src="234/234376_736471-lq.mp3" />
        </div>
      </div>
    );
  }
}

const DrumPad = (props) => { 
  return (
    <div className="drum-pad">
      <button id={props.id} onClick={props.handleClick}>
        <span>{props.innerText}</span>
        <audio id={props.innerText} className="clip">
          <source src={"https://freesound.org/data/previews/" + props.src} type="audio/mpeg" />
        </audio>
      </button>
    </div>
  )
}

const handleClickOld = (e) => {
  let btnText = e.target.innerHTML;
  audio = document.getElementById(btnText);
  audio.currentTime = 0;
  audio.play();
}

//console.clear();

ReactDOM.render(<DrumMachine />, document.getElementById('root'));

Welcome to the forum!

There is something that sticks out to me here:

What is this.state ?

Thanks :slight_smile: I just wrote that in when I was making my template. I haven’t used it for anything.

Welcome, fcccm.

Are you not wanting to pass the specific instance of handleClick to your onClick method? That is:
onClick={this.props.handleClick}

Same goes for the id.

Awesome yeah of course! I had to add handleClick={this.handleClick} to the DrumPad child component

<DrumPad id="Claves-1" innerText="Q" src="234/234367_736471-lq.mp3" handleClick={this.handleClick} />

and onClick={props.handleClick} inside the DrumPad component on the button.

<button id={props.id} onClick={props.handleClick}> <span>{props.innerText}</span> <audio id={props.innerText} className="clip"> <source src={"https://freesound.org/data/previews/" + props.src} type="audio/mpeg" /> </audio> </button>

Thanks!

So I tried to combine my handlers (onClick and the keydown event listener), and there are so many odd behaviors…

  • Button clicks work, but only after a short while, ie very delayed playback/laggy
  • Keydown can also be laggy at the beginning, but then works fine
  • Display only shows correct ID with keydown the first time I use keydown (I have not tried to hook up the display with onClick yet)

Was it a bad idea to combine my keydown and onclick handlers? I was trying to write less lines of code & not write similar code twice.

const drumButtons = ['Q','W','E','A','S','D','Z','X','C'];
let btnId = '';
let audio = '';
class DrumMachine extends React.Component {
  constructor(props) {
    super(props);
    // bind handlers
    this.handleClick = this.handleClick.bind(this);
  }
  // handlers
  handleClick = (e) => {
    if (e.type == 'click') {
      audio = document.getElementById(e.target.innerHTML);
    } else if (e.type == 'keydown' && drumButtons.includes(String.fromCharCode(e.keyCode))) {
      audio = document.getElementById(String.fromCharCode(e.keyCode));
      $('#display').html(e.target.id);
    } else if (e.type == 'keydown' && !drumButtons.includes(String.fromCharCode(e.keyCode))) {
      return;
    }
    audio.load();
    audio.currentTime = 0;
    audio.play();
  }
  componentDidMount() {
    document.addEventListener('keydown', this.handleClick);
  }
  componentWillUnmount() {
    document.removeEventListener('keydown', this.handleClick);
  }
  render() {
    return (
      <div id="drum-machine">
        <div id="display">Claves 1</div>
        <DrumPad id="Claves-1" innerText="Q" src="234/234367_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Claves-2" innerText="W" src="234/234366_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Claves-3" innerText="E" src="234/234365_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Tapekick-1" innerText="A" src="211/211422_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Tapekick-2" innerText="S" src="211/211420_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Tapekick-3" innerText="D" src="211/211418_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Tumbadora-1" innerText="Z" src="234/234374_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Tumbadora-2" innerText="X" src="234/234375_736471-lq.mp3" handleClick={this.handleClick} />
        <DrumPad id="Tumbadora-3" innerText="C" src="234/234376_736471-lq.mp3" handleClick={this.handleClick} />
      </div>
    );
  }
}

const DrumPad = (props) => { 
  return (
    <button id={props.id} className="drum-pad" onClick={props.handleClick}>
      <span>{props.innerText}</span>
      <audio id={props.innerText} className="clip" src={"https://freesound.org/data/previews/" + props.src} type="audio/mpeg" />
    </button>
  )
}

console.clear();

ReactDOM.render(<DrumMachine />, document.getElementById('root'));

Thank you.