Abstract ReactJS components
If you look for a clean and simple alternative to mixins for ReactiveJS ES6 components, read this.
Mixins was a way of implementing cross-cutting concerns in a DRY way with the old-style ReactJS components, a way to hook into your components’ life cycle.
In ReactJS components written using ES6 – or ECMAScript 6 – styled Javascript, the next version of Javascript, mixins are no longer an option.
There are workarounds to be found on the net, some more complex than others.
But in simple use cases an abstract base class seems to be a good fit. But does it work? The class specification may shine some light on it, but it isn’t apparent.
So I tried it:
class Base extends React.Component {
constructor() {
super();
if (this.doComponentDidMount === undefined) {
throw new TypeError(this.constructor.name + " must implement doComponentDidMount");
}
if (this.doComponentWillUnmount === undefined) {
throw new TypeError(this.constructor.name + " must implement doComponentWillUnmount");
}
}
componentDidMount() {
// implement your hook logic here
// ...
// then let the derived class finish the job
this.doComponentDidMount();
}
componentWillUnmount() {
this.doComponentWillUnmount();
}
}
And it works! There may be room for complex composition-patterns and high-order components, but often the simplest approach that works is the best.
If the abstract methods are optional, this becomes even shorter:
class Base extends React.Component {
componentDidMount() {
if (this.doComponentDidMount !== undefined) {
this.doComponentDidMount();
}
}
componentWillUnmount() {
if (this.doComponentWillUnmount !== undefined) {
this.doComponentWillUnmount();
}
}
}
There may not be enough templating going on in the examples above, but the closest well known pattern is probably the Template method pattern – widely used in Javascript’s name cousin Java.