ES7 introduces the concept of static
property and method definitions. Along with an ES7-capable transpiler, these can be used in React to specify validators and defaults for props
, like so:
export default class ComponentOne extends React.Component {
static propTypes = {
foo: React.PropTypes.string
}
static defaultProps = {
foo: 'bar'
}
// ...
}
This is super handy, but gets tricky when subclasses come into play. For example, say the following module is added to the same codebase as ComponentOne
above:
export default class ComponentTwo extends ComponentOne {
static propTypes = {
baz: React.PropTypes.number
}
static defaultProps = {
baz: 42
}
// ...
}
I'd like ComponentTwo
to "inherit" the property validators and defaults of its superclass, ComponentOne
. Instead, propTypes
and defaultProps
on ComponentTwo
shadow those on ComponentOne
, and React tosses out those defined on ComponentOne
.
Since super
is a reference to the current class's prototype, and static
is supposed to reference values hung directly off the prototype, I thought this might work:
import _ from 'lodash';
export default class ComponentTwo extends ComponentOne {
static propTypes = _.merge(super.propTypes, {
baz: React.PropTypes.number
});
}
However, this generates an error, presumably from Babel: Parsing error: 'super' outside of function or class
.
This works, but is not very portable:
export default class ComponentTwo extends ComponentOne {
static propTypes = Object.assign({
baz: React.PropTypes.number
}, ComponentOne.propTypes);
}
Are there any other ways to do this more cleanly/reusably?
The static keyword defines a static method or property for a class, or a class static initialization block (see the link for more information about this usage).
Static properties and methods are inherited. For class B extends A the prototype of the class B itself points to A : B.
TL;DR: Static properties are properties of a class, not of an instance of a class.
A static method in JavaScript is a method that has a static keyword prepended to itself. Such methods cannot be accessed through instantiated objects but could be accessed through the class name. This is because static methods belong to the class directly. Inheritance even applies to static methods.
I stumbled upon this question, and it's been almost 3 years, but who know, someone might need it. (And it's still relevant)
Given that when you extend a class it automatically inherits of its parent class, you would not need to overwrite the static propTypes
property.
Given a parent class:
class Parent {
static propTypes = {
parentProp: PropTypes.string
}
}
If you don't want to add other propTypes/defaultProps, you can simply:
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
If you want to explicitly tell that you extends Parent
propTypes, or add new propTypes:
class Children extends Parent {
static propTypes = {
...Parent.propTypes, // Yes, you can spread static properties like everything else
childProp: Proptypes.number,
}
}
Small note, for this to work properly with Babel, you might need to include the transform-es2015-classes
babel plugin in your plugins or preset. My .babelrc
:
"presets": [
["env", {
"include": ["transform-es2015-classes"]
}],
"stage-0",
"react"
],
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With