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?
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.
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.
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.
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.
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> } }
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With