Class decorators in ES7

自古美人都是妖i 提交于 2019-12-10 02:25:16

问题


I've been reading up on decorators in JavaScript, and think I'm getting the basic premise.

Decorators are functions, they receive as a or several parameters what they should decorate, and return the result.

But I came over a @withStyles decorated implementation in a React Boiler Plate project which I do not understand how works.

import React, { Component, PropTypes } from 'react';

function withStyles(...styles) {
  return (BaseComponent) => class StyledComponent extends Component {
    static contextTypes = {
      insertCss: PropTypes.func.isRequired,
    };

    componentWillMount() {
      this.removeCss = this.context.insertCss.apply(undefined, styles);
    }

    componentWillUnmount() {
      this.removeCss();
    }

    render() {
      return <BaseComponent {...this.props} />;
    }
  };
}

export default withStyles;

A use case would be

import s from './MyComponentStyle.scss';

@withStyles(s)
class MyComponent extends Component {

}

How does this work?


回答1:


Class decorators can be used as factory functions. For Example:

function myDecorator(value) {
   return function(target) {
      target.myProperty = value;
   }
}

@myDecorator('myValue')
class MyClass { }

In your example the factory function returns constructor function which wraps original class. This function is used to create object instead of the original class. In your case it handles events (componentWillMount, componentWillUnmount) in order to insert/remove css and renders the original component with it's props.

This is very simple example demonstrating how is the original constructor function overrided by decorator:

function myDecorator(name) {
   return (target) => class Wrapper {
       sayHello() {
           const targetObject = new target();
           console.log(`wrapper ${name} says hello`);
           targetObject.sayHello();
       }
       wrapperMethod() {
           console.log('calling wrapper function');
       }
   };
}

@myDecorator('Jack')
class MyClass {
    sayHello() {
        console.log('original says hello');
    }
    myMethod() {
       console.log('calling original function');
    }
}

var obj = new MyClass();

obj.sayHello();
//wrapper Jack says hello
//original says hello

obj.wrapperMethod();
//calling wrapper function

obj.myMethod();
//TypeError: obj.myMethod is not a function


来源:https://stackoverflow.com/questions/34766822/class-decorators-in-es7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!