在父类中扩展类和使用类属性

IT技术 javascript reactjs ecmascript-6 es6-class
2021-05-05 02:25:42

我试图解决 React 烦人的bind要求如下:

class ExtendedComponent extends React.Component {

    custom_functions: [];

    constructor(props){
        super(props);
        let self = this;
        for (let i = 0; i < this.custom_functions.length; i++) {
            let funcname = this.custom_functions[i];
            self[funcname] = self[funcname].bind(self);
        }
    }
}

class OrderMetricsController extends ExtendedComponent {

    custom_functions: ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];

    constructor(props){
        super(props);
        ...

这将排除需要

this.refreshTableOnDateChange = this.refreshTableOnDateChange.bind(this);

现在,我知道TypeError: Cannot read property 'length' of undefined问题出在哪里this.custom_functions.length

1个回答

custom_functions: ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];

是类型注解,this.custom_functions仍然是未定义的。相反,它应该是一个属性初始化器:

custom_functions = ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];

或者考虑到它的静态性质,custom_functions可以是一个静态属性:

static custom_functions = ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];

在这种情况下,它可以在构造函数中作为this.constructor.custom_functions.

没有什么烦人的bind,这就是 JS 的工作方式。

对于严格的命名约定,可以通过遍历方法名称来自动绑定方法,例如名称匹配的方法on**Handler

const uniquePropNames = new Set([
  ...Object.getOwnPropertyNames(this),  
  ...Object.getOwnPropertyNames(this.constructor.prototype)
]);

for (const propName of uniquePropNames) {
  if (typeof this[propName] === 'function' && /^on[A-Z]|.Handler$/.test(propName)) {
     this[propName] = this[propName].bind(this);
  }
}

一个不错的选择是@autobind装饰器来自core-decorators.