通过构造函数进行反应绑定 - 可以自动化吗?

React binding through constructor - possible to automate?

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

constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
}

我的组件有很多方法,我将所有这些方法绑定到 this。啊,好痛!为了避免重复维护这种模式,我构建了一个将在构造函数中调用的函数来代替所有单独的调用;它绑定了特定于 class 的所有方法,而父 class 会处理自己的方法,向上移动 classes。例如:

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();

那么,React 和 ES6 大师,这是一种合理的方法,还是我在这里做错了什么?我应该坚持对 this 的单独绑定吗?

假设你已经为它设置了 Babel,你也可以使用箭头函数来代替,避免绑定 this:

class Foo extends React.Component {
  handleClick = (event) => {
    event.preventDefault()
  }

  render() {
    return <div onClick={this.handleClick}>Click me</div>
  }
}

您的策略似乎很合理,但有些极端情况您可能最终想要解决。像 react-autobind, which 这样的库会为你处理其中的一些事情,如果我要使用这个策略,我可能会使用像这样的库(或者查看源代码以获得一个想法它的作用)。

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

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

    class MyComponent extends React.Component {
      handleChange = () => { /* ... */ }
    }
    
  2. 使用装饰器,如 autobind decorator from core-decorators,以及任何必要的 Babel 转换(这是我之前使用的策略):

    import { autobind } from 'core-decorators'
    
    class MyComponent extends React.Component {
      @autobind
      handleChange() { /* ... */ }
    }
    
  3. 探索 Hooks(目前处于 alpha 阶段)的使用,以避免绑定在一起的问题(因为状态值和设置器作为局部变量存在,需要关闭)。这是我最近一直偏爱的策略,但请注意,它仍处于提案状态,可能会发生变化。 :)

解决这个问题的一种方法是在渲染中调用绑定:

onChange={this.handleChange.bind(这个)}