在React

时间:2016-11-28 00:56:59

标签: javascript reactjs decorator ecmascript-next

如何将thistransform-decorators-legacy Babel插件绑定? 例如,我有一些简单的装饰器。装饰器有效,但this在组件方法上未定义。

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)
    }
}

如果我尝试将@myDecorator与一些@autobind装饰器一起使用,我会得到 TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute,因为

  

数据描述符是具有值的属性,该值可以是也可以不是可写的。访问器描述符是由getter-setter函数对描述的属性。描述符必须是这两种风格之一;它不可能都是。

在我的示例中,我无法使用value()get()

构造函数中的绑定(this.myMethod = thid.myMethod.bind(this))似乎也没有用,因为你绑定了未修饰的方法。

2 个答案:

答案 0 :(得分:1)

这不是.bind装饰方法的问题。

但是你错过了一些东西。即使您在.bindmyMethod constructor,但在调用它时,无论从何处,myDecorator都会修改执行范围。

oldValue.apply(null, arguments)

基本上,您将目标范围(MyClass)替换为null

所以你想要的是这个:

oldValue.apply(this, arguments)

看到这个小提琴:http://jsfiddle.net/free_soul/0n6v1dtp/

答案 1 :(得分:1)

这就是我设法解决这个问题的方法: 使用提到的@autobind装饰器中的代码:

function myDecorator(target, key, descriptor) {
    let fn = descriptor.value;

    return {
        configurable: true,

        get() {
            let boundFn = fn.bind(this);
            Reflect.defineProperty(this, key, {
                value: boundFn,
                configurable: true,
                writable: true
            });

            return function() {
                ...// Doing some stuff here I need the decorator for
                ...// (for example logging on every method call)
                return boundFn.apply(this, arguments)
            };
        }
    };
}