Nannnnnnn
Nannnnnnn

Reputation: 27

Can similar almost same onClick events combined in one dynamic onClick function in React?

My project is: when people click a <button> or <li> among a list of section, test, and practice etc. Each click will render a presentational component. My question is whether there is a solution to simplify my code as below.

    createSection = () => {
this.setState({
  sectionVisilibity: !this.state.sectionVisilibity
})

}

    createPractice = () => {
this.setState({
  practiceVisilibity: !this.state.practiceVisilibity
})
}

my initialstate is like this

    sectionVisilibity:false,
    practiceVisilibity:false,

And, the structure of state is

this.state={ 
          .....,
          sections:[
             sec1:{name:'',description:''},
             sec2:{...}
           ]
    }

My button group is like this

const BtnGroup = ({ createSection, createPractice }) => (
  <ul>
    <li onClick={createSection}>Section</li>
    <li onClick={createPractice}>Practice</li>
    <li onClick={createSubSec}>Subsection</li>
    <li onClick={createDownload}>Download</li>
    <li onClick={createTest}>Test</li> 
  </ul>
)

Are there a way I can write like

createComponent=()=> {
 //conditionally decide the click action by click event
 //The thing I confused about is I did not pass any event here, but the click is work. It can change the flag between true and false.  
}

Therefore, could anyone know how to grab value like multiple input I can use attribute to setState. How about onClick?

Thanks in advance!!

Upvotes: 0

Views: 67

Answers (3)

hannad rehman
hannad rehman

Reputation: 4341

I have a simple solution for this kind of problem. the basic problem here is how to pass parameters to a onClick function.

what i do in this kind of scenario is to use data attributes.

    handleClick(ev){
       const type = ev.target.dataset.clickType;
       // switch on type and you got the solution

    }


     const BtnGroup = ({ handleClick }) => (
             <ul>
                    <li data-click-type="session" onClick={handleClick}>Section</li>
                    <li data-click-type="practice" onClick={handleClick}>Practice</li>
                    <li data-click-type="subsection" onClick={handleClick}>Subsection</li>
                    <li data-click-type="download" onClick={handleClick}>Download</li>
                    <li data-click-type="test" onClick={handleClick}>Test</li> 
            </ul>
                )

if there is any click action that you want to map to the same handler . you just have to add the same data-click-type ="attribute"

in some cases you need to pass the entire object as an argument. that can also be achieved by using JSON.stringify`(ob)

also you are not creating any dynamic functions inside onClick which makes it more efficient.

Upvotes: 1

Amit Chauhan
Amit Chauhan

Reputation: 1884

There is two another way to do that. First is make an object of array of your state and then in same order set your li tags in which buttons are present. And on click send index also so that on the basis of index you can change state. Second is same take your state in object array and on click send name also like the above answer. And in your function you can use seitch case or if else condition which button has beej clicked by the name.

this.state = {
  data: [
          {createSection:false},
          {createBlock:false}
        ]
}

onClick(e,index,propertyName){
  let data = this.state.data;
  data[index].propertyName = true;
  this.setState({data:data});
}

<li key={index}> <button onClick 
 {(e)=>this.onClick(e,index,'createSection')}> Create Section </button> 
</li>
<li key={index}> <button onClick=
 {(e)=>this.onClick(e,index,'CreateBlock')}> Create Section </button> 
</li>

Keep that in mind that button order must be same as states.

Upvotes: 0

john_omalley
john_omalley

Reputation: 1398

You could in theory do some conditional logic on the event, but I don't think you want to do that.

Try something like:

    <li onClick={() => createComponent('practice')}>Practice</li>

Upvotes: 1

Related Questions