Decorator is the new feature of ES7! Well, it isn’t really a standard feature now. It’s in Stage 2, but, thanks to babel, we can use it immidiately.
Let’s see a very simple example:
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
Its purpose seems like what the Decorator Pattern does, right?
A decorator is the name used for a software design pattern. Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated.
Decorator signature:
function(target, property, descriptor){}
decorating method of class
class Person {
@readonly
name() { return `${this.first} ${this.last}` }
}
But we can not decorate function like this!
var counter = 0;
var add = function () {
counter++;
};
@add
function foo() {
}
because of function evaluation, the code above is working like this below
@add
function foo() {
}
var counter;
var add;
counter = 0;
add = function () {
counter++;
};
So we need to wrap the function in order to decorate.
const wrapper = add(foo);
OK, after looking at these features, I bet it would remind you of HOC in React.
React & Redux
class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
With decorator, we can write like this:
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}
some recommended decorator libraries:
react-decoration: A collection of @decorators for React Components
recompose: Recompose is a React utility belt for function components and higher-order components. Think of it like lodash for React.