React: How can I make a button to be triggered by a specific keys as well onClick events?

Basically I’m working on a drum machine project and I need each out of 9 buttons that will be showed on the screen to be clickable with the mouse click as well as by a related keyboard key.

Setting it up to work with mouse with onClick event attached to each button click was pretty straightforward, but I’m having difficulties with making it to work with the keyboard.

So far I have done the following:

  1. Set up componentDidMount() with an event listener to read each key press:
componentDidMount() {
   const setKey = (event) => { this.setState({ keyPressed: event.key.toUpperCase() }) }
   document.addEventListener('keydown', setKey);
}
  1. Set up componentDidUpdate() to check whether a currently pressed key is among keys that are used in the app, then it triggers handleClick function and passes couple arguments:
componentDidUpdate() {
   if (this.state.keyList.includes(this.state.keyPressed)) {
     this.handleClick("keydown", this.state.keyPressed)
   }
}
  1. Finally, handleClick checks whether it is a “keydown” or “click” event and plays the corresponding <audio> :
handleClick(event) {
   if (arguments[0] === "keydown") {
     var audio = document.getElementById(arguments[1])
   } else {
      const { name, value } = event.target
      this.setState({
         displayValue: value
      })
      var audio = document.getElementById(name)
   }
   audio.paused ? audio.play() : audio.currentTime = 0
}

My code is currently able to play corresponding audio for both scenarios, but I’m not sure how to make it display a corresponding value from the button in case when it is triggered by a keyboard button since I can’t figure out how to pass event.target as it is done for onClick scenario.

Also, probably the main issue, is that eventually I would like to set up CSS and Bootstrap for this project and the button should be changing it’s color when it is played, as well as when it is triggered by the keyboard. What I have done right now is rather a workaround and when the time comes to set it up, it won’t be working this way.

Is there anyway I could trigger buttons when a corresponding keyboard keys are pressed and behave in a way as it would when I do it via onClick ?

** My ReactJS code so far **

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      displayValue: "",
      keyPressed: "",
      keyList: ["Q", "W", "E", "A", "S", "D", "Z", "X", "C"]
    }
    this.handleClick = this.handleClick.bind(this)
  }
  
  componentDidMount() {
    const setKey = (event) => { this.setState({ keyPressed: event.key.toUpperCase() }) }
    document.addEventListener('keydown', setKey)
  }
  
  componentDidUpdate() {
    if (this.state.keyList.includes(this.state.keyPressed)) {
      this.handleClick("keydown", this.state.keyPressed)
    }
  }
  
  handleClick(event) {
    if (arguments[0] === "keydown") {
      var audio = document.getElementById(arguments[1])
    } else {
      const { name, value } = event.target
      this.setState({
        displayValue: value
      })
      var audio = document.getElementById(name)
    }
    audio.paused ? audio.play() : audio.currentTime = 0
  }
  
  render() {
    return (
      <div id="drum-machine">
        <div id="display">{this.state.displayValue}</div>
        
        <div className="drum-pad" id="pad-q">
          <button type="button" name={this.state.keyList[0]} value="Chord 1" onClick={this.handleClick}>Q</button>
          <audio className="clip" id={this.state.keyList[0]} src="https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-w">
          <button type="button" name={this.state.keyList[1]} value="Chord 2" onClick={this.handleClick}>W</button>
          <audio className="clip" id={this.state.keyList[1]} src="https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-e">
          <button type="button" name={this.state.keyList[2]} value="Chord 3" onClick={this.handleClick}>E</button>
          <audio className="clip" id={this.state.keyList[2]} src="https://s3.amazonaws.com/freecodecamp/drums/Chord_3.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-a">
          <button type="button" name={this.state.keyList[3]} value="Shaker" onClick={this.handleClick}>A</button>
          <audio className="clip" id={this.state.keyList[3]} src="https://s3.amazonaws.com/freecodecamp/drums/Give_us_a_light.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-s">
          <button type="button" name={this.state.keyList[4]} value="Open HH" onClick={this.handleClick}>S</button>
          <audio className="clip" id={this.state.keyList[4]} src="https://s3.amazonaws.com/freecodecamp/drums/Dry_Ohh.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-d">
          <button type="button" name={this.state.keyList[5]} value="Closed HH" onClick={this.handleClick}>D</button>
          <audio className="clip" id={this.state.keyList[5]} src="https://s3.amazonaws.com/freecodecamp/drums/Bld_H1.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-z">
          <button type="button" name={this.state.keyList[6]} value="Punchy Kick" onClick={this.handleClick}>Z</button>
          <audio className="clip" id={this.state.keyList[6]} src="https://s3.amazonaws.com/freecodecamp/drums/punchy_kick_1.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-x">
          <button type="button" name={this.state.keyList[7]} value="Side Stick" onClick={this.handleClick}>X</button>
          <audio className="clip" id={this.state.keyList[7]} src="https://s3.amazonaws.com/freecodecamp/drums/side_stick_1.mp3"/>
        </div>
        
        <div className="drum-pad" id="pad-c">
          <button type="button" name={this.state.keyList[8]} value="Snare" onClick={this.handleClick}>C</button>
          <audio className="clip" id={this.state.keyList[8]} src="https://s3.amazonaws.com/freecodecamp/drums/Brk_Snr.mp3"/>
        </div>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById("root"))

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36.

Challenge: Build a Drum Machine

Link to the challenge: