OlehZiniak OlehZiniak - 9 days ago 6
Javascript Question

Bind this when using method decorators in React

How to bind

this
with
transform-decorators-legacy
Babel plugin?
For example I have some simple decorator. Decorator works, but
this
is undefined on component's method.

fucntion myDecorator(target, name, descriptor) {
var oldValue = descriptor.value;

descriptor.value = function() {
...// Doing some stuff here I need the decorator for
...// (for example logging on every method call)
return oldValue.apply(null, arguments);
};

return descriptor;

}

class MyClass extends React.Component {
@myDecorator
myMethod() {
...// this.props... is unavailable here(`this` is undefined)
}
}


If I try to use @myDecorator with some @autobind decorators I get
TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute
, because


A data descriptor is a property that has a value, which may or may not be writable. An accessor descriptor is a property described by a getter-setter pair of functions. A descriptor must be one of these two flavors; it cannot be both.


In my example I can not use
value()
and
get()
.

Binding in the constructor (
this.myMethod = thid.myMethod.bind(this)
) doesn't seem to be helpful either, because you bind undecorated method.

Answer

Is it not the problem with .binding decorated methods.

But there is something that you missed. Even though you did .bind your myMethod inside your constructor to the class, when you invoke it, no matter from where, myDecorator modifies the execution scope.

oldValue.apply(null, arguments)

Basically, you replaced target scope (MyClass) with null.

So what you want is this:

oldValue.apply(this, arguments)

See this fiddle: http://jsfiddle.net/free_soul/0n6v1dtp/