8

ES7 引入了static属性和方法定义的概念。与支持 ES7 的转译器一起,这些可以在 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. 取而代之的是propTypesdefaultProps在.ComponentTwoComponentOneComponentOne

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

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

但是,这会产生一个错误,可能来自 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);
}

有没有其他方法可以更干净/可重用地做到这一点?

4

2 回答 2

1

我偶然发现了这个问题,已经快 3 年了,但谁知道呢,有人可能需要它。(它仍然是相关的)

鉴于当您扩展一个类时,它会自动继承其父类,您不需要覆盖该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"
],

希望这可以帮助!

于 2018-08-09T15:56:04.263 回答
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();
于 2015-12-14T00:43:12.057 回答