Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to turn on React.js autobinding for React's class model

According to this blog post feature that bounds all methods in React.createClass to this is not built-in in React's class model.

Is it possible to turn it on by default?

I know that it's possible to use this.someMethod = this.ticksomeMethod.bind(this); trick do manually do this, but is it possible to do it for all methods? Or am I forced to write bind for all methods?

Example of code I have now:

import MessageStore from '../stores/MessageStore.js';

export default class Feed extends React.Component {
   constructor() {
      this.state = {messages: MessageStore.getAll()}
      //can I avoid writing this for every single method?
      this._onChange = this._onChange.bind(this); 
   }

   _onChange() {
       this.setState({messages: MessageStore.getAll()});
   };

   // componentDidMount, componentWillUnmount and render methods ommited
}
like image 573
ivstas Avatar asked Sep 29 '22 09:09

ivstas


2 Answers

There is no feature to activate that does this in React currently. It's simply not an option.

You could post-process a class and automatically bind every function, but that's likely unnecessary in many classes, and adds overhead to every call (as your code will probably have a mixture of functions needing binding and some that don't).

You'll need to decide whether automatic adjustment is worth it or just using the bind syntax in the context of event callbacks, the typical place it's required in JavaScript, is acceptable.

like image 68
WiredPrairie Avatar answered Oct 02 '22 16:10

WiredPrairie


There is a new solution using the elegant @decorator syntax. You have to enable the JavaScript ES2015 stage-0 features for Babel, but after that it's a breeze! You can then just write:

import autobind from 'autobind-decorator'
// (...)
<li onClick={ this.closeFeedback }>Close</li>
// (...)
@autobind
closeFeedback() {
  this.setState( { closed: true } );
}

To get that to work, you need to install some build libraries. Here's how:

npm install --save-dev babel-preset-stage-0
npm install --save-dev babel-plugin-react-transform
npm install --save-dev babel-plugin-transform-decorators-legacy
npm install --save-dev autobind-decorator

Or wrap them all together in one command:

npm install --save-dev babel-preset-stage-0 babel-plugin-react-transform babel-plugin-transform-decorators-legacy autobind-decorator

After that change your .babelrc or webpack.config.js depending on where you specify your babel settings:

query: {
  presets: ['es2015', 'react', 'stage-0'],
  plugins: [['transform-decorators-legacy']]
}

(Note that in a .babelrc file the root node start at the query object.)

Good luck and don't forget the import statement!

like image 44
Micros Avatar answered Oct 02 '22 16:10

Micros