I’ve been working on the drum machine project (linked below) for a while now, and have had quite a bit of trouble. Through searching the forum and other resources I’ve managed to get audio to play by clicking on the element, but I have been unable to handle the keymapping feature.
(I have not implemented any CSS so far, and have only worked on 1 drumpad element.)
In the handler function, you can use event.key to get the key pressed, it corresponds to the id on the audio element (in lower case). So you can use that to get to the audio element.
@lasjorg Thank you very much! This seems to be working fine, and I’ve tried it with the next element as well. However, the name that shows up on clicking the element doesn’t seem to be working with the keypress despite using the same setState method, and I noticed onClick requires 2 clicks to play audio. Can you help with that?
I think it has to do with the props you are passing down and updating their values in the setState.
You don’t need the key or the name inside the child, so I would remove the props. The name should be inside a single element with the id #display, you can just create an element in the main parent component.
<div id="display">{this.state.name}</div>
As an aside, I would not hardcode the buttons and values inside the DrumPad component. It would be better to use an array of objects (or an object of objects) and map it in the JSX. You have the beginning of that already in the commented out code at the top.
I removed the props as you suggested, which has resolved the 2 clicks issue, but the name still doesn’t show on keypress. I’m working on mapping the array into JSX part.
Thank you
Why isn’t the name being displayed on keypress events even when the same setState method has been used? It works on clicking the element, and I’m not using the same method of rendering components as before
It is the handler you have attached in componentDidMount to the document that is called when pressing a button, not the onKeyPress you have on the element. So you are not getting any arguments passed to the handler function (other than the event).
As an aside. Technically, you can still call the inline handler by clicking the button so it has focus and then press the corresponding keyboard button and it will fire the inline handler, but that isn’t very useful.
One option might be to get the key that was pressed, use that to get the audio element and then get the parent element. The parent element id is the name.
Can you please explain how one would get the audio element from the key and so on? I have managed to solve my issue by modifying the function, but I’d like to know what else could have been done.
event.key is the key that was pressed. It is in lower case, so you need to uppercase it. Use that for the audio element selector (by id). Now you have a reference to the audio element (and can call play on it as well).
You can get to the parent element id using parentElement.id on the audio element reference.