我是用React使用ES6类的新手,以前我一直在绑定我的方法到当前对象(在第一个例子中显示),但ES6允许我永久绑定一个类函数到一个类实例与箭头?(在作为回调函数传递时有用。)我得到错误时,我试图使用他们,因为你可以与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);
  }

如果我要通过某个类。handleInputChange to,例如setTimeout,它的作用域是类实例,而不是窗口对象。


当前回答

我知道这个问题已经得到了充分的回答,但我还有一个小小的贡献要做(对于那些不想使用实验功能的人)。由于必须在构造函数中绑定多个函数绑定的问题,使它看起来很混乱,我提出了一个实用方法,一旦在构造函数中绑定和调用,就会自动为您执行所有必要的方法绑定。

假设我有一个带有构造函数的类:

//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 /组件/ PetEditor.jsx import React from import {bindMethodsToSelf} from '../utils'; 类PetEditor扩展React。组件{ 构造函数(道具){ 超级(道具); 这一点。状态=道具。currentPet || {tags:[], photoUrls: []}; 这一点。tagInput = null; 这一点。htmlNode = null; bindMethodsToSelf.bind(这)(PetEditor); } / /…… }

其他回答

你的语法有点错误,只是在属性名后面少了一个等号。

class SomeClass extends React.Component {
  handleInputChange = (val) => {
    console.log('selectionMade: ', val);
  }
}

这是一个实验特性。你需要在Babel中启用实验特性来编译。这里是一个实验启用的演示。

要使用babel的实验功能,您可以从这里安装相关的插件。对于这个特定的特性,你需要transform-class-properties插件:

{
  "plugins": [
    "transform-class-properties"
  ]
}

你可以在这里阅读更多关于类字段和静态属性的建议


不,如果你想创建绑定的,特定于实例的方法,你必须在构造函数中这样做。但是,你可以使用箭头函数,而不是在原型方法上使用.bind:

class SomeClass extends React.Component {
  constructor() {
    super();
    this.handleInputChange = (val) => {
      console.log('selectionMade: ', val, this);
    };
    …
  }
}

有一种建议可能允许您省略构造函数(),并直接将赋值放在具有相同功能的类作用域中,但我不建议使用这种方法,因为它是高度实验性的。

或者,您总是可以使用.bind,它允许您在原型上声明方法,然后将其绑定到构造函数中的实例。这种方法具有更大的灵活性,因为它允许从类外部修改方法。

class SomeClass extends React.Component {
  constructor() {
    super();
    this.handleInputChange = this.handleInputChange.bind(this);
    …
  }
  handleInputChange(val) {
    console.log('selectionMade: ', val, this);
  }
}

我知道这个问题已经得到了充分的回答,但我还有一个小小的贡献要做(对于那些不想使用实验功能的人)。由于必须在构造函数中绑定多个函数绑定的问题,使它看起来很混乱,我提出了一个实用方法,一旦在构造函数中绑定和调用,就会自动为您执行所有必要的方法绑定。

假设我有一个带有构造函数的类:

//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 /组件/ PetEditor.jsx import React from import {bindMethodsToSelf} from '../utils'; 类PetEditor扩展React。组件{ 构造函数(道具){ 超级(道具); 这一点。状态=道具。currentPet || {tags:[], photoUrls: []}; 这一点。tagInput = null; 这一点。htmlNode = null; bindMethodsToSelf.bind(这)(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);
  }
}

另外,不建议直接在渲染中绑定函数。它应该总是在构造函数中