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

时间:2015-10-23 22:59:03

标签: javascript inheritance static reactjs ecmascript-7

ES7引入了static属性和方法定义的概念。除了支持ES7的转换器,这些can be used in React还可以为props指定验证器和默认值,如下所示:

export default class ComponentOne extends React.Component {
    static propTypes = {
        foo: React.PropTypes.string
    }
    static defaultProps = {
        foo: 'bar'
    }
    // ...
}

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

export default class ComponentTwo extends ComponentOne {
    static propTypes = {
        baz: React.PropTypes.number
    }
    static defaultProps = {
        baz: 42
    }
    // ...
}

我希望ComponentTwo能够继承"继承"属性验证器及其超类ComponentOne的默认值。相反,propTypes上的defaultPropsComponentTwo会影响ComponentOne上的ComponentOne,并且React会删除super上定义的内容。

由于static是对当前类原型的引用,而import _ from 'lodash'; export default class ComponentTwo extends ComponentOne { static propTypes = _.merge(super.propTypes, { baz: React.PropTypes.number }); } 应该引用直接挂在原型上的值,我认为这可能有效:

Parsing error: 'super' outside of function or class

但是,这会产生错误,大概来自Babel:export default class ComponentTwo extends ComponentOne { static propTypes = Object.assign({ baz: React.PropTypes.number }, ComponentOne.propTypes); }

这有效,但不是很便携:

{{1}}

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

2 个答案:

答案 0 :(得分:0)

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

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

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

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

答案 1 :(得分:0)

我偶然发现了这个问题,已经快三年了,但是谁知道,有人可能需要它。 (并且仍然有意义)

鉴于扩展类时,它会自动继承其父类,则无需覆盖static propTypes属性。

给出一个父类:

class Parent {
  static propTypes = {
    parentProp: PropTypes.string
  }
}

如果您不想添加其他propTypes / defaultProps,则只需:

class Children extends Parent {
  // Do not declare the propTypes, it will extends by itself.
}
console.log(Children.propTypes); // Will output an object with parentProp in it

如果您想明确地告诉您扩展Parent propTypes或添加新的propTypes:

class Children extends Parent {
  static propTypes = {
    ...Parent.propTypes, // Yes, you can spread static properties like everything else
    childProp: Proptypes.number,
  }
}

请注意,为了使其与Babel一起正常工作,您可能需要在插件或预设中包含transform-es2015-classes babel插件。我的.babelrc

"presets": [
  ["env", {
    "include": ["transform-es2015-classes"]
  }],
  "stage-0",
  "react"
],

希望这会有所帮助!