是否可以为 React 的 class 模型打开 React.js 自动绑定
Is it possible to turn on React.js autobinding for React's class model
根据 this blog post 将 React.createClass
中的所有方法绑定到 this
的特性在 React 的 class 中 不是内置的 ] 模特.
是否可以默认打开它?
我知道可以使用 this.someMethod = this.ticksomeMethod.bind(this);
技巧手动执行此操作,但是否可以 对所有方法都执行此操作?或者我是否被迫为所有方法编写 bind
?
我现在的代码示例:
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
}
目前 React 中没有激活功能可以执行此操作。这根本不是一个选择。
您可以 post 处理 class 并自动 bind
每个函数,但这在许多 classes 中可能是不必要的,并且会增加每次调用的开销 (因为您的代码可能会混合需要绑定的函数和一些不需要的函数)。
您需要决定自动调整是否值得,或者仅在事件回调的上下文中使用 bind
语法,JavaScript 中需要它的典型位置是可以接受的。
有一个使用优雅的@decorator 语法的新解决方案。
您必须为 Babel 启用 JavaScript ES2015 stage-0 功能,但之后就变得轻而易举了!
然后你可以写:
import autobind from 'autobind-decorator'
// (...)
<li onClick={ this.closeFeedback }>Close</li>
// (...)
@autobind
closeFeedback() {
this.setState( { closed: true } );
}
要使其正常工作,您需要安装一些构建库。方法如下:
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
或者将它们全部打包在一个命令中:
npm install --save-dev babel-preset-stage-0 babel-plugin-react-transform babel-plugin-transform-decorators-legacy autobind-decorator
之后,根据您指定的 babel 设置更改 .babelrc
或 webpack.config.js
:
query: {
presets: ['es2015', 'react', 'stage-0'],
plugins: [['transform-decorators-legacy']]
}
(请注意,在 .babelrc
文件中,根节点从查询对象开始。)
祝你好运,不要忘记导入语句!
如果您不想或还不能使用 babel 装饰器语法。您可以定义一个自动绑定函数并在 class 中添加一行样板来处理自动绑定。
function autobind(target) { // <-- Define your autobind helper
for (let prop of Object.getOwnPropertyNames(Object.getPrototypeOf(target))) {
if (typeof target[prop] !== 'function') {
continue;
}
if (~target[prop].toString().replace(/\s/g, '').search(`^${prop}[(][^)]*[)][{;][\'\"]autobind[\'\"];`)) {
target[prop] = target[prop].bind(target);
}
}
}
class Test {
constructor() {
autobind(this); // <- single line of boilerplate
this.message = 'message';
}
method1(){ return this.method2(); }
method2(){ console.log(this.message);}
_handleClick() { 'autobind'; // <-- autobind searches for functions with 'autobind' as their first expression.
console.log(this.message);
}
}
let test = new Test();
let _handleClick = test._handleClick;
_handleClick();
根据 this blog post 将 React.createClass
中的所有方法绑定到 this
的特性在 React 的 class 中 不是内置的 ] 模特.
是否可以默认打开它?
我知道可以使用 this.someMethod = this.ticksomeMethod.bind(this);
技巧手动执行此操作,但是否可以 对所有方法都执行此操作?或者我是否被迫为所有方法编写 bind
?
我现在的代码示例:
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
}
目前 React 中没有激活功能可以执行此操作。这根本不是一个选择。
您可以 post 处理 class 并自动 bind
每个函数,但这在许多 classes 中可能是不必要的,并且会增加每次调用的开销 (因为您的代码可能会混合需要绑定的函数和一些不需要的函数)。
您需要决定自动调整是否值得,或者仅在事件回调的上下文中使用 bind
语法,JavaScript 中需要它的典型位置是可以接受的。
有一个使用优雅的@decorator 语法的新解决方案。 您必须为 Babel 启用 JavaScript ES2015 stage-0 功能,但之后就变得轻而易举了! 然后你可以写:
import autobind from 'autobind-decorator'
// (...)
<li onClick={ this.closeFeedback }>Close</li>
// (...)
@autobind
closeFeedback() {
this.setState( { closed: true } );
}
要使其正常工作,您需要安装一些构建库。方法如下:
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
或者将它们全部打包在一个命令中:
npm install --save-dev babel-preset-stage-0 babel-plugin-react-transform babel-plugin-transform-decorators-legacy autobind-decorator
之后,根据您指定的 babel 设置更改 .babelrc
或 webpack.config.js
:
query: {
presets: ['es2015', 'react', 'stage-0'],
plugins: [['transform-decorators-legacy']]
}
(请注意,在 .babelrc
文件中,根节点从查询对象开始。)
祝你好运,不要忘记导入语句!
如果您不想或还不能使用 babel 装饰器语法。您可以定义一个自动绑定函数并在 class 中添加一行样板来处理自动绑定。
function autobind(target) { // <-- Define your autobind helper
for (let prop of Object.getOwnPropertyNames(Object.getPrototypeOf(target))) {
if (typeof target[prop] !== 'function') {
continue;
}
if (~target[prop].toString().replace(/\s/g, '').search(`^${prop}[(][^)]*[)][{;][\'\"]autobind[\'\"];`)) {
target[prop] = target[prop].bind(target);
}
}
}
class Test {
constructor() {
autobind(this); // <- single line of boilerplate
this.message = 'message';
}
method1(){ return this.method2(); }
method2(){ console.log(this.message);}
_handleClick() { 'autobind'; // <-- autobind searches for functions with 'autobind' as their first expression.
console.log(this.message);
}
}
let test = new Test();
let _handleClick = test._handleClick;
_handleClick();