Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value of this in React event handler

Tags:

For some reason the value of this is being lost in react event handler. Reading the docs I thought that react did some stuff here to make sure this was set to the correct value

The following doesn't work as I'd expect

import React from 'react';  export default class Observer extends React.Component {      handleClick() {         console.log(this); //logs undefined     }     render() {         return (             <button onClick={this.handleClick}>Click</button>         );     } } 

But this does:

import React from 'react';  export default class Observer extends React.Component {      handleClick() {         console.log(this); //logs Observer class instance     }     render() {         return (             <button onClick={this.handleClick.bind(this)}>Click</button>         );     } } 

React and ES6 is new to me but this seems to not be the correct behaviour?

like image 902
jamie holliday Avatar asked Apr 19 '15 15:04

jamie holliday


People also ask

Why is this undefined In React event handler?

This is because when you use an arrow function, the event handler is automatically bound to the component instance so you don't need to bind it in the constructor. When you use an arrow function you are binding this lexically.

Why do we need to bind this in React?

Binding methods helps ensure that the second snippet works the same way as the first one. With React, typically you only need to bind the methods you pass to other components. For example, <button onClick={this. handleClick}> passes this.

Which value should you pass to event listener props like onClick?

Pass a Button's Value as a Parameter Through the onClick Event Handler. You might want to pass in the value or name of the button or input element through the event handler.

What is handleClick in React?

In the Toggle class, a handleClick method is defined as an instance method, which changes the local state. In the render method, this. handleClick is passed to the button as an event handler. Finally, do not forget to bind this to handleClick in the constructor.


2 Answers

This is correct behavior for JavaScript and React if you use the new class syntax.

The autobinding feature does not apply to ES6 classes in v0.13.0.

So you'll need to use:

 <button onClick={this.handleClick.bind(this)}>Click</button> 

Or one of the other tricks:

export default class Observer extends React.Component {   constructor() {     super();     this.handleClick = this.handleClick.bind(this);   }   handleClick() {     /* ... */   }   render() {       return <button onClick={this.handleClick}>Click</button>   } } 
like image 174
WiredPrairie Avatar answered Oct 06 '22 08:10

WiredPrairie


The accepted answer is good and I've used it a lot in ES6, but I just want to add another "more modern" solution we have with ES7 (mentioned in the React component class auto-binding notes): use arrow functions as class properties, then you don't need to bind or wrap your handler anywhere.

export default class Observer extends React.Component {   handleClick = (e) => {     /* ... */   }   render() {       return <button onClick={this.handleClick}>Click</button>   } } 

This is the simplest and cleanest solution yet!

like image 21
Aaron Beall Avatar answered Oct 06 '22 08:10

Aaron Beall