通过构造器反应绑定-可以自动化吗?

Cha*_*man 1 ecmascript-6 reactjs es6-class

根据其他人的建议,我一直在React的构造函数中绑定类方法,例如:

constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
}
Run Code Online (Sandbox Code Playgroud)

我的组件中包含许多方法,并且将所有这些方法都绑定到this。啊,真痛苦!为了避免重复维护此模式,我构建了一个在构造函数中代替所有单独调用的函数;它绑定了特定于该类的所有方法,而父类将照顾自己的方法,将这些类向上移动。例如:

function bindClassMethodsToThis(classPrototype, obj) {
    Object.getOwnPropertyNames(classPrototype).forEach(prop => {
        if (obj[prop] instanceof Function && prop !== 'constructor') {
            obj[prop] = obj[prop].bind(obj);
            console.log(`${classPrototype.constructor.name} class binding ${prop} to object`);
        }
    });
}

class A {
    constructor() {
        bindClassMethodsToThis(A.prototype, this);
    }

    cat() {
        console.log('cat method');
    }
}

class B extends A {
    constructor() {
        super();
        bindClassMethodsToThis(B.prototype, this);
    }

    dog() {
        console.log('dog method');
    }
}

let b = new B();
Run Code Online (Sandbox Code Playgroud)

那么,React和ES6专家,这是一种合理的方法,还是我在这里做错了?我应该坚持对此的个人束缚吗?

Mic*_*ley 5

您的策略似乎不错,尽管您可能最终想解决一些极端情况。就像一个图书馆react-autobind,其中亚历山大提到,需要照顾的一些事情对你来说,如果我是使用这种策略,我可能会使用类似这样的库(或者看看到的源代码,以获得一个想法是什么它确实)。

为了完整性,一些替代方法是:

  1. 使用类属性和箭头函数(以及任何必要的Babel变换)来创建预绑定方法:

    class MyComponent extends React.Component {
      handleChange = () => { /* ... */ }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用装饰器,例如autobindcore-decorators的装饰器,以及任何必要的Babel变换(这是我之前使用的策略):

    import { autobind } from 'core-decorators'
    
    class MyComponent extends React.Component {
      @autobind
      handleChange() { /* ... */ }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 探索Hooks的用法(当前在Alpha中),以避免将所有内容绑定在一起的问题(因为状态值和设置器作为要封闭的局部变量存在)。这是我最近一直比较喜欢的策略,但是请注意,该策略仍处于提案状态,并且可能会更改。:)