在React.js中覆盖/扩展ES7类上的静态属性

eri*_*oco 8 javascript inheritance static reactjs ecmascript-7

ES7引入了static属性和方法定义的概念.与支持ES7的转换器一起,这些可以在React中用于指定验证器和默认值props,如下所示:

export default class ComponentOne extends React.Component {
    static propTypes = {
        foo: React.PropTypes.string
    }
    static defaultProps = {
        foo: 'bar'
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这非常方便,但是当子类发挥作用时会变得棘手.例如,假设以下模块添加到与ComponentOne上面相同的代码库中:

export default class ComponentTwo extends ComponentOne {
    static propTypes = {
        baz: React.PropTypes.number
    }
    static defaultProps = {
        baz: 42
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我想ComponentTwo"继承"其超类的属性验证器和默认值ComponentOne.相反,propTypesdefaultPropsComponentTwo影子上ComponentOne,和React抛出那些定义ComponentOne.

既然super是对当前类原型的引用,并且static应该引用直接挂在原型上的值,我认为这可能有效:

import _ from 'lodash';
export default class ComponentTwo extends ComponentOne {
    static propTypes = _.merge(super.propTypes, {
        baz: React.PropTypes.number
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,这会产生一个错误,大概来自Babel : Parsing error: 'super' outside of function or class.

这有效,但不是很便携:

export default class ComponentTwo extends ComponentOne {
    static propTypes = Object.assign({
        baz: React.PropTypes.number
    }, ComponentOne.propTypes);
}
Run Code Online (Sandbox Code Playgroud)

还有其他方法可以更干净/可重复使用吗?

Jor*_*dão 0

奇怪的是,使用super静态方法有效。我认为它也应该适用于静态属性。那么,对我来说,直接使用超类名称感觉更自然:

export default class ComponentTwo extends ComponentOne {
  static propTypes = _.merge({}, ComponentOne.propTypes, {
    baz: React.PropTypes.number
  });
}
Run Code Online (Sandbox Code Playgroud)

但是,要使用super,我能想到的一种解决方法是使用静态方法来初始化属性,不幸的是必须手动调用:

class ComponentTwo extends ComponentOne {
  static _init() { 
    this.propTypes = _.merge({}, super.propTypes, {
      baz: React.PropTypes.number
    });
  }
}
ComponentTwo._init();
Run Code Online (Sandbox Code Playgroud)