Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnClick Event binding in React.js

I would like to pass the parent div id, on click of that div or any child element of the same div. But I am unable to achieve it. Please tell me where I am making a mistake. Code is below:

viewMore: function(i,j){         console.log('You clicked: ', i  );     },  render : function(){   var attributeId = "groups_";   attributeId+= index;   return(   //parent div     <div className="groups" id={attributeId} onClick={this.viewMore}>         <div className="floatLeft"> Group Name: <h3>My Name</h3></div>             <span className="floatRight typeCd">POC</span>         <div className="clearfix"> Key Attributes:              <ul>                 <li> POC 1</li>             </ul>         </div>     </div>     ) }; 
like image 289
Swaraj Ghosh Avatar asked Dec 10 '14 09:12

Swaraj Ghosh


People also ask

How do you show text after onClick in React JS?

You can either create an element with JS and append it to the form body or you can have an invisible div/p/whatever element that gets his text modified inside the onclick function and its css class/css style too so that it appears.

How do you call a button click event in React JS?

Implementing JavaScript `click` Event To add the click event in React using plain JavaScript, you need to use addEventListener() to assign the click event to an element. Create one <button> element as ref props so that it can be accessed to trigger the click event.


2 Answers

viewMore = (i,j) => () => {     console.log(i,j) } 

To pass parameters to event handlers we need to use currying. With the above method no new functions created all the time while render is called.

like image 82
Henrik Andersson Avatar answered Sep 25 '22 05:09

Henrik Andersson


Since I see these kind of suggestions in multiple places, I am going to move my comment into an answer as well, to provide an additional view:

class TestComponent extends React.Component {   constructor() {     super();     this.onClick = this.handleClick.bind(this);   }    handleClick(event) {     const {id} = event.target;     console.log(id);   }    render() {     return (       <div>         <h3 id={this.props.id} onClick={this.onClick}>           {this.props.name}         </h3>       </div>     );   } } 

This allows to:

  1. avoid unnecessary binds
  2. access the id and whatever else properties in a much more React-ive manner.

Of course, the above example assumes that you receive the id as a prop, but you can do the necessary manipulations as well.

UPDATE 1 -- Nov 28, 2016

Added link to CodePen from comments above.

UPDATE 2 -- Mar 30, 2017

As mentioned, this wouldn't work if you use React.createClass to define your components. You don't have a constructor to pull this off. You can use other lifecycle methods, if you don't mind a little ugliness.

Having said that, it is 2017. Use ES6, would you?!

UPDATE 3 -- May 12, 2017

If you are using class properties transform, then you can simplify it further:

class TestComponent extends React.Component {   onClick = (event) => {     const {id} = event.target;     console.log(id);   }    render() {     return (       <div>         <h3 id={this.props.id} onClick={this.onClick}>           {this.props.name}         </h3>       </div>     );   } } 

UPDATE 4 -- Feb 4, 2018

Due to improvements of bind and friends in V8 (Chakra and such probably too), you just may be better off using the this.click.bind(this) or wrapping it in an arrow function when passing to onClick.

Why?

The previous method, created for performance reasons only, closed some possibilities for dynamically injecting functions onto the component's prototype.

NOTE 1 -- Apr 14, 2018

Keep in mind that the method mentioned in Update 4 still introduces some performance issues, as on each render pass a new function is created as a result of bind. This, in turn, will trickle down to the child component and cause unnecessary re-renders, as the function changes each time.

The same thing happens when you pass an arrow function inline.

All other methods, like using class properties, will mess with your inheritance (which you should be avoiding, but still), simply due to the fact that, currently, Babel transpiles them to "on-instance" functions, which are not on the prototype chain.

So, this:

class Person {   printA = () => { console.log('a') } } 

becomes:

function _classCallCheck(instance, Constructor) {...abridged...}  var Person = function Person() {   _classCallCheck(this, Person);    this.printA = function () {     console.log('a');   }; }; 
like image 31
ZenMaster Avatar answered Sep 25 '22 05:09

ZenMaster