Salman
Salman

Reputation: 9447

Decorate react component to add lifecycle methods

I am trying to create a decorator method which will add some default lifecycle methods into the react component. My objective is to add some default functionality into the component, for example all component should be able to do a specific thing on componentWillMount.

I read a couple of articles and found this. It can be used to add new props to the react components.

export default function context(contextTypes, context) {

    return function (DecoratedComponent) {
        return class {
            static childContextTypes = contextTypes;
            getChildContext() {
              return context;
            }
            render() {
              return (
                <DecoratedComponent {...this.props} />
              );
            }
        }
    }
}

But I am not sure how would I add class methods like componentWillMount. Can I do something like

Object.assign(DecoratedComponent.prototype, {
    componentWillMount: () => {
        // do something
    }
})

Any idea towards right direction?

Refs:

http://asaf.github.io/blog/2015/06/23/extending-behavior-of-react-components-by-es6-decorators/ https://gist.github.com/motiz88/3db323f018975efce575

Upvotes: 2

Views: 1698

Answers (1)

Andrew Faulkner
Andrew Faulkner

Reputation: 3940

If you're using Babel with the stage 1 or stage 0 preset, you can use the following method:

First, define your decorator function, e.g.:

function lifecycleDefaults(target) {
    target.prototype.componentWillMount = function() {
        console.log('componentWillMount ran from decorator!');
        console.log('this.props is still accessible', this.props);
    }
    target.prototype.componentWillUnmount = function() {
        console.log('componentWillUnmount ran from decorator!');
        console.log('this.props is still accessible', this.props);
    }
    target.prototype.componentDidMount = function() {
        console.log('componentDidMount ran from decorator!');
        console.log('this.props is still accessible', this.props);
    }
}

Following that, decorate a component using the function you just defined e.g.:

@lifecycleDefaults
export class Page extends React.Component {
    render() {
        return (
            <div>Hello decorators!</div>
        );
    }
};

Component 'Page' now has methods componentWillMount, componentDidMount, and componentWillUnmount. They run at the expected times in the component's lifecycle.

2 caveats: 1) I'm using the babel transform-decorators-legacy plugin; 2) I'm building my project using Webpack, with babel's transform-runtime included. YMMV.

Upvotes: 2

Related Questions