Javascript 覆盖/扩展React.js中ES7类的静态属性
ES7引入了Javascript 覆盖/扩展React.js中ES7类的静态属性,javascript,inheritance,static,reactjs,ecmascript-2016,Javascript,Inheritance,Static,Reactjs,Ecmascript 2016,ES7引入了静态属性和方法定义的概念。与支持ES7的transpiler一起,它们可以指定道具的验证器和默认值,如下所示: export default class ComponentOne extends React.Component { static propTypes = { foo: React.PropTypes.string } static defaultProps = { foo: 'bar' } // .
静态属性和方法定义的概念。与支持ES7的transpiler一起,它们可以指定道具的验证器和默认值,如下所示:
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
的属性验证器和默认值。相反,ComponentTwo上的propTypes
和defaultProps
将ComponentOne
上的属性隐藏起来,React将ComponentOne
上定义的属性抛出
由于super
是对当前类的原型的引用,而static
应该引用直接挂起原型的值,因此我认为这可能会起作用:
import _ from 'lodash';
export default class ComponentTwo extends ComponentOne {
static propTypes = _.merge(super.propTypes, {
baz: React.PropTypes.number
});
}
但是,这会产生一个错误,可能是因为Babel:解析错误:“super”在函数或类之外
这是可行的,但不是很便于携带:
export default class ComponentTwo extends ComponentOne {
static propTypes = Object.assign({
baz: React.PropTypes.number
}, ComponentOne.propTypes);
}
还有其他更干净/可重用的方法吗?奇怪的是,使用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();
我偶然发现了这个问题,已经快3年了,但谁知道,可能有人需要它。(这仍然是相关的)
假设在扩展一个类时它会自动继承其父类,那么就不需要覆盖static propTypes
属性
给定父类:
class Parent {
static propTypes = {
parentProp: PropTypes.string
}
}
如果您不想添加其他道具类型/默认道具,您可以简单地:
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"
],
希望这有帮助 继承具有静态属性的类时,请注意以下注意事项:“如果您是从类继承,那么静态属性将通过\uuuu proto\uuuu
从类继承,这一点得到广泛支持,但您可能会在使用更旧的浏览器时遇到问题。注意:\uuuu proto\uuuu
在IE上不受支持。你试过在构造函数中合并超级.propTypes
吗?@Mat我没有,但是考虑到props
进入构造函数时已经设置了默认值,我想那太晚了。这不只是我文章末尾建议的重构吗?使用lodash
而不是对象。分配
?我的问题是显式引用ComponentOne
,而不是能够引用“super”类。这没什么大不了的,因为您必须在extends
语句中引用它,但这并不理想。是的,确实如此,但使用merge的方法是正确的。还添加了另一种选择,我认为更糟糕。您可能可以通过使用静态get propTypes()摆脱ini函数