问题
I have tried to solve React's annoying bind
requirement as follows:
class ExtendedComponent extends React.Component {
custom_functions: [];
constructor(props){
super(props);
let self = this;
for (let i = 0; i < this.custom_functions.length; i++) {
let funcname = this.custom_functions[i];
self[funcname] = self[funcname].bind(self);
}
}
}
class OrderMetricsController extends ExtendedComponent {
custom_functions: ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];
constructor(props){
super(props);
...
This will preclude the need for
this.refreshTableOnDateChange = this.refreshTableOnDateChange.bind(this);
For now, I get TypeError: Cannot read property 'length' of undefined
where the problem is this.custom_functions.length
.
回答1:
This
custom_functions: ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];
is type annotation, and this.custom_functions
is still undefined. Instead, it should be a property initializer:
custom_functions = ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];
Or considering its static nature, custom_functions
can be a static property:
static custom_functions = ['refreshTableOnDateChange', 'load', 'refreshTableOnTabChange'];
In this case it is accessible in constructor as this.constructor.custom_functions
.
There's nothing annoying in bind
, this is how JS works.
For strict naming conventions, the methods can be bound automatically by traversing through method names, for example the ones which names match on*
or *Handler
:
const uniquePropNames = new Set([
...Object.getOwnPropertyNames(this),
...Object.getOwnPropertyNames(this.constructor.prototype)
]);
for (const propName of uniquePropNames) {
if (typeof this[propName] === 'function' && /^on[A-Z]|.Handler$/.test(propName)) {
this[propName] = this[propName].bind(this);
}
}
A good alternative is @autobind decorator from core-decorators.
来源:https://stackoverflow.com/questions/42261671/extending-classes-and-using-class-attributes-in-parent-class