如何使用箭头函数(public class 字段)作为 class 方法?
How to use arrow functions (public class fields) as class methods?
我刚开始使用 ES6 classes 和 React,之前我一直将我的方法绑定到当前对象(在第一个示例中显示),但是 ES6 是否允许我永久绑定 class 函数到带箭头的 class 实例? (当作为回调函数传递时很有用。)当我尝试像使用 CoffeeScript 一样使用它们时出现错误:
class SomeClass extends React.Component {
// Instead of this
constructor(){
this.handleInputChange = this.handleInputChange.bind(this)
}
// Can I somehow do this? Am i just getting the syntax wrong?
handleInputChange (val) => {
console.log('selectionMade: ', val);
}
因此,如果我要将 SomeClass.handleInputChange
传递给,例如 setTimeout
,它将被限定为 class 实例,而不是 window
对象。
您的语法略有偏差,只是在 属性 名称后缺少一个等号。
class SomeClass extends React.Component {
handleInputChange = (val) => {
console.log('selectionMade: ', val);
}
}
这是一项实验性功能。您将需要在 Babel 中启用实验性功能才能进行编译。 Here 是启用了实验性的演示。
要在 babel 中使用实验性功能,您可以从 here. For this specific feature, you need the transform-class-properties
plugin 安装相关插件:
{
"plugins": [
"transform-class-properties"
]
}
您可以阅读有关 Class 字段和静态属性的提案的更多信息 here
不,如果您想创建绑定的、特定于实例的方法,您将必须在构造函数中执行此操作。但是,您可以为此使用箭头函数,而不是在原型方法上使用 .bind
:
class SomeClass extends React.Component {
constructor() {
super();
this.handleInputChange = (val) => {
console.log('selectionMade: ', val, this);
};
…
}
}
有一个 proposal 可能允许您省略 constructor()
并直接将赋值放在具有相同功能的 class 范围内,但我不建议这样做使用它,因为它具有高度实验性。
或者,您始终可以使用 .bind
,它允许您在原型上声明方法,然后将其绑定到构造函数中的实例。这种方法具有更大的灵活性,因为它允许从 class.
外部修改方法
class SomeClass extends React.Component {
constructor() {
super();
this.handleInputChange = this.handleInputChange.bind(this);
…
}
handleInputChange(val) {
console.log('selectionMade: ', val, this);
}
}
我知道这个问题已经得到了充分的回答,但我只能做出一点贡献(对于那些不想使用实验性功能的人)。由于必须在构造函数中绑定多个函数绑定并使其看起来很乱,我想出了一个实用方法,一旦在构造函数中绑定和调用,就会自动为您完成所有必要的方法绑定。
假设我有这个 class 和构造函数:
//src/components/PetEditor.jsx
import React from 'react';
class PetEditor extends React.Component {
constructor(props){
super(props);
this.state = props.currentPet || {tags:[], photoUrls: []};
this.tagInput = null;
this.htmlNode = null;
this.removeTag = this.removeTag.bind(this);
this.handleChange = this.handleChange.bind(this);
this.modifyState = this.modifyState.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
this.addTag = this.addTag.bind(this);
this.removeTag = this.removeTag.bind(this);
this.savePet = this.savePet.bind(this);
this.addPhotoInput = this.addPhotoInput.bind(this);
this.handleSelect = this.handleSelect.bind(this);
}
// ... actual method declarations omitted
}
看起来很乱,不是吗?
现在我创建了这个实用方法
//src/utils/index.js
/**
* NB: to use this method, you need to bind it to the object instance calling it
*/
export function bindMethodsToSelf(objClass, otherMethodsToIgnore=[]){
const self = this;
Object.getOwnPropertyNames(objClass.prototype)
.forEach(method => {
//skip constructor, render and any overrides of lifecycle methods
if(method.startsWith('component')
|| method==='constructor'
|| method==='render') return;
//any other methods you don't want bound to self
if(otherMethodsToIgnore.indexOf(method)>-1) return;
//bind all other methods to class instance
self[method] = self[method].bind(self);
});
}
我现在需要做的就是导入该实用程序,并添加对我的构造函数的调用,我不再需要在构造函数中绑定每个新方法。
新的构造函数现在看起来很干净,像这样:
//src/components/PetEditor.jsx
import React from 'react';
import { bindMethodsToSelf } from '../utils';
class PetEditor extends React.Component {
constructor(props){
super(props);
this.state = props.currentPet || {tags:[], photoUrls: []};
this.tagInput = null;
this.htmlNode = null;
bindMethodsToSelf.bind(this)(PetEditor);
}
// ...
}
您正在使用箭头函数并将其绑定到构造函数中。所以你使用箭头函数时不需要绑定
class SomeClass extends React.Component {
handleInputChange = (val) => {
console.log('selectionMade: ', val);
}
}
或者当你像下面这样使用普通函数时,你只需要在构造函数中绑定一个函数
class SomeClass extends React.Component {
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(val){
console.log('selectionMade: ', val);
}
}
不建议直接在渲染中绑定函数。它应该总是在构造函数中
我刚开始使用 ES6 classes 和 React,之前我一直将我的方法绑定到当前对象(在第一个示例中显示),但是 ES6 是否允许我永久绑定 class 函数到带箭头的 class 实例? (当作为回调函数传递时很有用。)当我尝试像使用 CoffeeScript 一样使用它们时出现错误:
class SomeClass extends React.Component {
// Instead of this
constructor(){
this.handleInputChange = this.handleInputChange.bind(this)
}
// Can I somehow do this? Am i just getting the syntax wrong?
handleInputChange (val) => {
console.log('selectionMade: ', val);
}
因此,如果我要将 SomeClass.handleInputChange
传递给,例如 setTimeout
,它将被限定为 class 实例,而不是 window
对象。
您的语法略有偏差,只是在 属性 名称后缺少一个等号。
class SomeClass extends React.Component {
handleInputChange = (val) => {
console.log('selectionMade: ', val);
}
}
这是一项实验性功能。您将需要在 Babel 中启用实验性功能才能进行编译。 Here 是启用了实验性的演示。
要在 babel 中使用实验性功能,您可以从 here. For this specific feature, you need the transform-class-properties
plugin 安装相关插件:
{
"plugins": [
"transform-class-properties"
]
}
您可以阅读有关 Class 字段和静态属性的提案的更多信息 here
不,如果您想创建绑定的、特定于实例的方法,您将必须在构造函数中执行此操作。但是,您可以为此使用箭头函数,而不是在原型方法上使用 .bind
:
class SomeClass extends React.Component {
constructor() {
super();
this.handleInputChange = (val) => {
console.log('selectionMade: ', val, this);
};
…
}
}
有一个 proposal 可能允许您省略 constructor()
并直接将赋值放在具有相同功能的 class 范围内,但我不建议这样做使用它,因为它具有高度实验性。
或者,您始终可以使用 .bind
,它允许您在原型上声明方法,然后将其绑定到构造函数中的实例。这种方法具有更大的灵活性,因为它允许从 class.
class SomeClass extends React.Component {
constructor() {
super();
this.handleInputChange = this.handleInputChange.bind(this);
…
}
handleInputChange(val) {
console.log('selectionMade: ', val, this);
}
}
我知道这个问题已经得到了充分的回答,但我只能做出一点贡献(对于那些不想使用实验性功能的人)。由于必须在构造函数中绑定多个函数绑定并使其看起来很乱,我想出了一个实用方法,一旦在构造函数中绑定和调用,就会自动为您完成所有必要的方法绑定。
假设我有这个 class 和构造函数:
//src/components/PetEditor.jsx
import React from 'react';
class PetEditor extends React.Component {
constructor(props){
super(props);
this.state = props.currentPet || {tags:[], photoUrls: []};
this.tagInput = null;
this.htmlNode = null;
this.removeTag = this.removeTag.bind(this);
this.handleChange = this.handleChange.bind(this);
this.modifyState = this.modifyState.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
this.addTag = this.addTag.bind(this);
this.removeTag = this.removeTag.bind(this);
this.savePet = this.savePet.bind(this);
this.addPhotoInput = this.addPhotoInput.bind(this);
this.handleSelect = this.handleSelect.bind(this);
}
// ... actual method declarations omitted
}
看起来很乱,不是吗? 现在我创建了这个实用方法
//src/utils/index.js
/**
* NB: to use this method, you need to bind it to the object instance calling it
*/
export function bindMethodsToSelf(objClass, otherMethodsToIgnore=[]){
const self = this;
Object.getOwnPropertyNames(objClass.prototype)
.forEach(method => {
//skip constructor, render and any overrides of lifecycle methods
if(method.startsWith('component')
|| method==='constructor'
|| method==='render') return;
//any other methods you don't want bound to self
if(otherMethodsToIgnore.indexOf(method)>-1) return;
//bind all other methods to class instance
self[method] = self[method].bind(self);
});
}
我现在需要做的就是导入该实用程序,并添加对我的构造函数的调用,我不再需要在构造函数中绑定每个新方法。 新的构造函数现在看起来很干净,像这样:
//src/components/PetEditor.jsx
import React from 'react';
import { bindMethodsToSelf } from '../utils';
class PetEditor extends React.Component {
constructor(props){
super(props);
this.state = props.currentPet || {tags:[], photoUrls: []};
this.tagInput = null;
this.htmlNode = null;
bindMethodsToSelf.bind(this)(PetEditor);
}
// ...
}
您正在使用箭头函数并将其绑定到构造函数中。所以你使用箭头函数时不需要绑定
class SomeClass extends React.Component {
handleInputChange = (val) => {
console.log('selectionMade: ', val);
}
}
或者当你像下面这样使用普通函数时,你只需要在构造函数中绑定一个函数
class SomeClass extends React.Component {
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(val){
console.log('selectionMade: ', val);
}
}
不建议直接在渲染中绑定函数。它应该总是在构造函数中