Rendering Elements in React (Drum Machine Challenge)

Working on the drum machine challenge, codepen here.

Problem is my drum pad elements are only partially rendering. I have two classes building them, the DrumPad class. Here’s its render component:

 render() {
    return(
      //check props ref to audio link 
    <div id={this.props.id}
      onClick={this.playSound}
      className="drum-pad">
      <audio className='clip' id={this.props.keyTrigger} src={this.props.url}></audio>
      {this.props.keyTrigger}
      </div>
      )
  }

And the PadBank class, which renders like so:

 render() {
 let padBank = soundBank.map((bank) => {
       return (
          <DrumPad 
						clipId={bank.id} 
						clip="#"
						keyTrigger={bank.keyTrigger}
						keyCode={bank.keyCode} 
						 />
        )
      });
    
   return (
      <div className="pad-bank" >
				{padBank}
			</div>
  )
 }

This is yes very similar to the example, I tried to simplify it to one sound bank. But when rendered, and I inspect, besides having no functionality, the pads render missing most of their elements:

<div id="drum-machine" class="inner-container"><div class="pad-bank"><div class="drum-pad"><audio class="clip" id="Q"></audio>Q</div><div class="drum-pad"><audio class="clip" id="W"></audio>W</div>

I’m not sure why all elements of the DrumPad (div id, audio src) are not rendering, and it seems like the code is iterating through the map function (at least, it is interpreted and runs) but then the added attributes of clipID, keyTrigger, etc. are not rendering.

Can anyone help me understand this problem? Thanks in advance.

After the keyCode prop, you should add url={bank.url} and it will start to sound every time you press a screen key. For the keyboard keys, I would add a tabIndex to the PadBank render() main div. I would add an onKeyDown event handler here that triggers screen key presses.

Btw, great job! Nice, sleek, and efficient code! I have to refactor mine. It took me like 1,000 lines of code to get to where you are at in your Drum Machine, and now I am close to 1,900. I am still working on mine.

I thought the following would handle the key press and audio play: (No?)

class DrumPad extends React.Component {
  constructor(props) {
    super(props);
    this.state ={}
   this.playSound = this.playSound.bind(this);
   this.handleKeyPress = this.handleKeyPress(this);
}
  componentDidMount() {
    document.addEventListener('keydown', this.handleKeyPress);
  }
   handleKeyPress(e) {
     if (e.keycode === this.props.keyCode){
       this.playSound();
     }
   }
  playSound(e){
    const sound = document.getElementById(this.props.keyTrigger); // because Audio ID = keyTrigger
    sound.currentTime = 0;
    sound.play();
  }

And thank you for the compliment but mostly I “was inspired by” no-stack-dub-sack’s idea and tried to strip away the niceities (extra bank, audio, power) to the bare functionality.

Edit: if I add url:{bank.url} after the keyCode in PadBank, I can click to get sound, but the keypress is not working … ? Will look into it.

I thought the following would handle the key press and audio play: (No?)

I am struggling with this project, but yes, that seems to handle it. I did some research and that’s a better way than what I ended up using. I didn’t know that you could just use document without any additional getElementById or querySelector. I really like the way you did your project and will be refactoring mine. I basically did mine in vanilla JavaScript within a React framework. I did not follow the principles of React and ended up manipulating the actual DOM and did not do as many components as I should have. After a lot of help from this section of the freeCodeCamp forum and Colt’s course, I now have a better idea of what React really is.

Keep up the good work!