具有React组件的装饰器 [英] Decorators with React Components

查看:295
本文介绍了具有React组件的装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很高兴能够使用 @myDecorator 语法(使用babel)。我试图装饰一个生命周期函数,特别是 componentWillMount ,并检查 props 装饰器中组件的上下文。但是,我似乎无法访问 props context 。我不确定这是否是一种反模式,或者我是否只是出错了。

I am very excited about the ability to use the @myDecorator syntax (using babel). I am trying to decorate one of the life cycle functions, specifically componentWillMount, and check the props and context of the component within the decorator. However, I seem to not be able to access either the props or context. I am not sure if this is sort of an anti pattern or if I am just going about this wrong.

小例子:

// TestComponent.jsx
import checkProps from 'checkProps.js';

class TestComponent extends React.Component {
    @checkProps
    componentWillMount() {
        // Do something.
    }

    render() {
       return <div>My Component</div>
    } 
}

// checkProps.js
export function checkProps(target) {
    console.log(target.props);
}

我还尝试了装饰器的箭头功能并检查这个,但我不认为装饰者会以这种方式组成东西。

I have also tried arrow functions for the decorator and checking this, but I don't think decorators compose things to work that way.

我也尝试让我的装饰工厂成为工厂并通过在 this.props this.context 但是是在装饰组件生命周期函数时未定义。

I have also tried making my decorator a factory and passing in this.props and this.context but this is undefined when decorating a component life cycle function.

推荐答案

ES7 ECMAScript装饰器 Object.defineProperty相同的API(目标,名称,描述符) 所以目标参数是你的装饰器应用时的类,而不是它的时候由 React 调用。要影响装饰器在运行时所做的事情,你必须修改 descriptor.value 这是装饰的实际函数:

ES7 ECMAScript Decorators have the same API as Object.defineProperty(target, name, descriptor) so the target parameter is your class at the time your decorator is applied, not at the time it is called by React. To influence what the decorator is doing at runtime you have to modify descriptor.value that is the actual function that is decorated:

export function checkProps(target, name, descriptor) {
    // Save the original method, it'd be a good idea
    // to check that it really is a function
    const decoratee = descriptor.value;

    // Modify the descriptor to return our decorator
    // function instead of the original
    descriptor.value = function decorated(...args) {
        // Do something before ...
        console.log('before: ' + name, this.props, args);

        // Calling the decorated method on this object
        // with some arguments that could have been 
        // augmented by this decorator
        decoratee.apply(this, args);

        // Do something after ...
        console.log('after: ' + name);
    };
} 

// Or if you wanted to use a factory function to supply some configuration
// to the decorator you can do it this way

export function checkProps(config) {
    return function configurableCheckProps(target, name, descriptor) {
        // Save the original method, it'd be a good idea
        // to check that it really is a function
        const decoratee = descriptor.value;

        if (config.someOption) {
            // Do something based on the config
        }

        // Modify the descriptor to return our decorator
        // function instead of the original
        descriptor.value = function decorated(...args) {
            // Do something before ...
            console.log('before: ' + name, this.props, args);

            if (config.someOption) {
                // Do something based on the config
            }

            // Calling the decorated method on this object
            // with some arguments that could have been 
            // augmented by this decorator
            decoratee.apply(this, args);

            // Do something after ...
            console.log('after: ' + name);
        };
    };
} 

这是一个也修改方法行为的例子更彻底地证明了这一点。

Here's an example that also modifies the behavior of a method that demonstrates this more thoroughly.

希望这会有所帮助。快乐的编码!

Hope this helps. Happy coding!

编辑:正如评论者所指出的,装饰者不是ES7的一部分,但截至2016年3月提案仍在第1阶段,我的不好

As a commenter pointed out, decorators are not part of ES7 but as of March 2016 the proposal is still in Stage 1, my bad

EDIT2:截至2018年6月该提案是在提案仍处于第2阶段,我们越来越近了

As of June 2018 the proposal is in the proposal is still in Stage 2, we're getting closer

这篇关于具有React组件的装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆