React.js: Differentiating between component of the same class

Hello campers,

I’m starting the drum machine project, making a map of the component tree I’ll need, it looks like this:

main
   ---tempo
   ---launch
   ---pads
         ---pad1
         ---pad2
         ---pad3
         ---pad4
         ---pad5
         ---pad6
         ---pad7
         ---pad8
         ---pad9
   ---sequencer
         ---sixteenth1
         ---sixteenth2
         ---etc

I’m beggining to understand a React component structure, however I don’t really understand how to do with the many pads or sixteenth elements. I would like for the pads to be generated from one unique class and pass their index via a prop. I’m not sure how to do to get each of my pad having a different action.

I want to store the states of my pads in the main component so that the sequencer can access them, the state would look like this:

main.state.pad =  [
           {
               index: 1,
               focus: 1,
               sequencer: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
           },
           {
               index: 2,
               focus: 0,
               sequencer: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
           },
           etc
       ];

I’m looking for the proper method to do this, I was thinking of using conditonal rendering depending on the index prop passed when generating the pads. Then use this index to modify main.state.pad[index].

Is this a good way of thinking in react? I would like to know if you have some advice, thank you!

Hey there,

I never done this project so take my ideas with the grain of salt. But generally speaking you are on the right path.

Creating a reusable component that does something passed on props should be fairly straightforward.

const pad = (props) => <div>My Pad with the unique behavior</div>

In the parent component you can indicate how many of these pad components do you want to render. If you keep a list of them in the state, you can use .map to render them all.

class Parent extends.....{
  render(){
//grab the array from state here!
const { pads } = this.state
//create a list of items from that
const padList = pads.map(pad => <li>{pad}</li>)
return(
  <ul>
   {padList}
  </ul>
 )
}}

Were you thinking along same lines? React is all about creating components that can be reused so I think you are definitely on the right track!

Thank you for your answer.
Yes that was the kind of thing I was thinking of using.
I’ll get back to you when I can with a CodePen, but for now I’m kind of struggling with my nested state.
I found this answer https://stackoverflow.com/questions/43040721/how-to-update-nested-state-properties-in-react#51136076 saying that I just shouldn’t use nested state, and instead have a state looking like this:

state = {
   tempo: 90,
   playing: false,
   padToFocus: null,
   pad1sequencer: [1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0]
   pad2sequencer: [0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0]
   pad3sequencer: [0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0]
   etc...
}

It seems less clear to me, is it good practice?

Can you explain why you need nested state? Why can you not just pass what is in effect the configuration for each pad via the props?

I don’t need nested state, that’s just the first way I imagined making it, it seemed logical to me. But I understand this can cause a lot of problems so I didn’t use it.

Here is what I have for now:
Drum rack

So this is the first time I try to use a proper way of creating a React app, could you check if it seems ok? Especially for the callback function that goes from grand-child to grand-parent, I had a hard time making it work.

In the grand-parent :

    this.getFocus = this.getFocus.bind(this);
  } 
  
  getFocus(focusIndex) {
    this.setState({
      padToFocus: focusIndex
    });
  }

and

<Pads currentFocus={this.state.padToFocus} getFocus={(i) => this.getFocus(i)}/>

In the parent:

pads.push(<Pad currentFocus={this.props.currentFocus}index={i} getFocus={() => this.props.getFocus(i)} />);

and finally in the grand-child:

pad = <button key={"pad" + index} className="pad" onClick={() => this.props.getFocus()} />

I had a hard time figuring out when I should put the arg inside of the () => or inside of the `getFocus()’ and I still don’t understand what exactly is happening.