When coding a react component in my spare time. It seems like when logging out this
to the console it should have a value.
export default class FootballPlayerComponent extends Component { render() { return ( <div className="football-player-controls"> <button name="purchase" onClick={this.purchasePlayer}> Purchase </button> </div> ); } purchasePlayer() { console.log(this); //Undefined } }
JSFiddle: https://jsfiddle.net/davebeaumont/tujzar6c/1/
After a bit of investigation and help from Stackoverflow, I found a few solutions, some of which were better than others. In ES5 it allows me to bind this
to the function in the constructor which then ensures this
has a value inside the function. It works, but certainly isn’t an ideal solution and will impact performance. Due to the increased code and complexity, it does not look great. (ES5 bind example below)
export default class FootballPlayerComponent extends Component { constructor() { super(); this.purchasePlayer = this.purchasePlayer.bind(this); } render() { return ( <div className="football-player-controls"> <button name="purchase" onClick={this.purchasePlayer}> Purchase </button> </div> ); } purchasePlayer() { //This is now populated thanks to the ES5 bind syntax in the constructor. console.log(this); } }
JSFiddle: https://jsfiddle.net/davebeaumont/tujzar6c/2/
Better still in ES6 I could utilize the arrow function which will lexically apply the binding of this
to a function. Allowing me to retain the scope of its caller inside the function automatically. This means we do not need to add any bind syntax to the constructor. this
refers to the code that contains the arrow function. This scenario produces less code, the scoping is simplified, and in my opinion, it appears more readable.
export default class FootballPlayerComponent extends Component { render() { return ( <div className="football-player-controls"> <button name="purchase" onClick={this.purchasePlayer}> Purchase </button> </div> ); } purchasePlayer = () => { //This is now populated inside an ES6 arrow function. console.log(this); } }
JSFiddle: https://jsfiddle.net/davebeaumont/tujzar6c/3/
Browser Support
At the time of writing this blog every browser except IE support’s arrow functions.