React Drum Machine question?

I restarted the Drum Machine in React because I was having trouble with it before. Right now it’s only working on my PC, but the code is on CodePen.

Also I’m trying to divide it into different files instead of all in the same one. So I have:
drums.js - An array with info for each button.
App.js - Passes the drums.js array into ButtonList.js. Then returns it.
ButtonList.js - Maps out buttons into Buttons.js. Then returns it.
Buttons.js - Creates buttons and assigns them id, keyCode, keyTrigger, url, desc. Then returns it.

1: Is this a good way to setup the files? I was trying to imitate a tutorial for a similar app I watched, where it said to divide up files into smaller pieces.

2: My playSound() and handleKeyPress() functions are inside the App constructor in App.js. And my buttons are in Buttons.js. I need to attach an onClick event to the buttons… but how do I target the function in App.js? Or should I put the handleKeyPress() function in the same file, Buttons.js?

3: I put the files on CodePen but the project isn’t loading there. Do I need to change the index.js file into an index.html file?

1. Yes

2. Just like you pass drums as props to ButtonList you can pass functions as props.

3. In index.js is this line:

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

which finds element with id root in index.html and attaches <App/> to it.
You need to create index.html with an element (usually <div>) with id root

Also for React projects I would use

Oh… So if I’m passing it down like the array from drums.js, I need to pass it from App.js to ButtonList.js to Buttons.js. I’d do something like this?

<ButtonList buttons={drums} clicker={this.handleClick} />


const ButtonList = ({ buttons, clicker }) => {
<Buttons ... clicker={clicker} />


const Button = ({ id, keyCode, keyTrigger, url, desc, clicker }) => {
<button ... onClick={()=>`${clicker}`}>{keyTrigger}</button>


What’s that?

I was trying to pass the function on to the item, but everytime I click one of the buttons I get this warning in console:
Uncaught Invariant Violation: Expected onClick listener to be a function, instead got a value of string type.

I googled it and I thought it was because it was reading the function as a string, but it doesn’t seem to help. Also I uploaded it to codesandbox:

Since you are already in javascript because of curly brackets. You can simply do this assuming that clicker is a function.

onClick={() => clicker()}

Make sure you are adding parentheses after clicker otherwise it will only return the function definition.


If you simply want to call the function:

<button ... onClick={clicker}>{keyTrigger}</button>

If you want to call the function with arguments:

<button ... onClick={someArg => clicker(someArg)}>{keyTrigger}</button>

Here is an example,
Good luck on your project,

1 Like

Thank you so much guys! I got it working now.

@jenovs and @shimphillip - I ended up using this:
<div … onClick={() => clicker(${keyTrigger}, ${id})}>
clicker is the function being called, and it’s passing keyTrigger and id in as parameters. I couldn’t-

EDIT: Never mind, this is even simpler:
<div ... onClick={() => clicker(keyTrigger, id)}>