Recently, I've started tinkering with React.js and I love it. I started out in the regular ES5, so as to get the hang of things, the docs are all written in ES5...
But now I wanted to try ES6, because it's shiny and new, and it does seem to simplify some things. What bothers me a lot is that for every method I had added into my component classes I now have to bind 'this' to, otherwise it doesn't work. So my constructor ends up looking like this:
constructor(props) { super(props); this.state = { ...some initial state... } this.someHandler = this.someHandler.bind(this); this.someHandler = this.someHandler.bind(this); this.someHandler = this.someHandler.bind(this); this.someHandler = this.someHandler.bind(this); this.someHandler = this.someHandler.bind(this); this.someHandler = this.someHandler.bind(this); this.someHandler = this.someHandler.bind(this); }
If I were to add even more methods to my class, this would become an even bigger, uglier mess.
My question is, is there some way to get around this, or at least make it easier, shorter and less ugly? One of the main reasons I wanted to try React with ES6 was to make my code more concise, but this is doing the opposite. Any suggestions or input would be appreciated.
To avoid the need for binding we have something introduced in ES6 as arrow functions. Using the arrow function to call this. setState will lead to avoid the use of bind.
This is why we need to bind event handlers in Class Components in React. While working on React, you must have come across controlled components and event handlers. We need to bind these methods to the component instance using . bind() in our custom component's constructor.
Use arrow functions to avoid binding `this` to methods: Binding this to handleClick in the constructor allows us to use this. setState from Component inside handleClick . Without this binding, this is re-scoped for handleClick and therefore cannot be used with the setState method.
Is it OK to use arrow functions in render methods? Generally speaking, yes, it is OK, and it is often the easiest way to pass parameters to callback functions. If you do have performance issues, by all means, optimize!
In ReactJs, when we are working with class-based components and want to access this inside a class method. This will need to bind it. Binding this allows it to access the state and setstate inside the class. To avoid the need for binding we have something introduced in ES6 as arrow functions.
One way to avoid binding in render is to bind in the constructor (the other approach is discussed in #5 below). This is the approach currently recommended in the React docs for “better performance in your application”. This is also the approach I use in “ Building Applications with React and Redux in ES6 ” on Pluralsight.
There are at least five ways to handle the this context in React. Let’s consider the merits of each approach. 1. Use React.createClass If you use React.createClass, React autobinds all functions to this.
If you use React.createClass, React autobinds all functions to this. So the this keyword is bound to your component’s instance automatically: However, with the advent of ES6 classes, this non-standard approach to creating classes isn’t the future of React. In fact, createClass is likely to be extracted from React core in a future release.
You can use class fields to do the binding outside the constructor. They look like the following:
class Foo extends React.Component { handleBar = () => { console.log('neat'); }; handleFoo = () => { console.log('cool'); }; render() { return ( <div onClick={this.handleBar} onMouseOver={this.handleFoo} /> ); } }
Class fields are supported experimentally by Babel via its class properties transform, but they are still "experimental" because they are a Stage 3 Draft (not yet in a Babel preset).
You will need to do the binding manually until ES7 or until enabling the feature in Babel, however. This topic is covered briefly in Babel's blog post on React on ES6+.
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