Reactive Component Decorators

I am very pleased to be able to use the syntax @myDecorator(using babel). I'm trying to decorate one of the life-cycle functions, in particular componentWillMount, to check propsand contextcomponent designers. However, it seems like I cannot access propsor context. I'm not sure if this is a kind of anti-pattern, or if I'm just wrong.

A small example:

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

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

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

and

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

I also tried the arrow functions for the decorator and tested this, but I don't think decorators compose things this way.

I also tried to make my factory decorator and pass this.propsand this.context, but this- undefined when decorating the component's life cycle function.

+4
1

ES7 ECMAScript API, Object.defineProperty(target, name, descriptor), target - , , , React. , , descriptor.value, , :

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

, , .

, . !

EDIT: , ES7, 2016 1,

+7

All Articles