React ES6,如何将装饰器保存在单独的文件中

时间:2017-08-18 06:30:58

标签: javascript reactjs ecmascript-6 babel-decorator

我们在ReactApp中创建了许多装饰器。

现在我们必须在每个文件中编写装饰器,我的典型代码看起来像这样。

******** MyComponent.js *************

import {Decorators} from 'decoratorLib';
import React, {Component} from 'react';

const {ModuleLoader, ModuleConfig, log} = Decorators;

@ModuleLoader({
    config: {
        k1: 'Value 1',
        k2: 'Value 2',
        viewClass: ModuleViewClass,
        ...moduleConfig
    },

    propTypes: {
        name: PropTypes.string.isRequired,
        age: PropTypes.number,
        address: PropTypes.string,
        quantity: PropTypes.number
    }
})

@ModuleConfig({
    config: {
        k1: 'Value 1',
        k2: 'Value 2',
        viewClass: ModuleViewClass,
        ...moduleConfig
    }
})

@log({
    config: {
        warning: true,
        error: true,
        breakOnError:false
    }
})
class MyComponent extends Component {

}

我想知道如何,我们可以在sperate文件中编写这些装饰器,然后写一些桥来传递/连接类

就像我可以有一个 decorators.js 文件一样,在这里编写所有装饰器,然后编写一些方法或注入器将它们注入类中。

2 个答案:

答案 0 :(得分:1)

装饰器实际上是一个功能

@decorator1(args)
@decorator2(args)
class Decorated {}

只是功能组合和应用

Decorated = decorator1(args)(decorator2(args)(Decorated))

所以你可以事先组成所有的装饰者

// decorators.js
const compose = (fns...) => init => fns.reduceRight((res, fn) => fn(res), init)

export default compose(
    ModuleLoader({
        config: {
            k1: 'Value 1',
            k2: 'Value 2',
            viewClass: ModuleViewClass,
            ...moduleConfig
        },

        propTypes: {
            name: PropTypes.string.isRequired,
            age: PropTypes.number,
            address: PropTypes.string,
            quantity: PropTypes.number
        }
    }),
    ModuleConfig({
        config: {
            k1: 'Value 1',
            k2: 'Value 2',
            viewClass: ModuleViewClass,
            ...moduleConfig
        }
    }),
    log({
        config: {
            warning: true,
            error: true,
            breakOnError: false
        }
    })
)

然后只是

import decorate from './decorators'

@decorate
class MyComponent extends Component {

}

答案 1 :(得分:0)

装饰器只是值,因此您可以将代码更改为

const loaderDecorator = ModuleLoader({
    config: {
        k1: 'Value 1',
        k2: 'Value 2',
        viewClass: ModuleViewClass,
        ...moduleConfig
    },

    propTypes: {
        name: PropTypes.string.isRequired,
        age: PropTypes.number,
        address: PropTypes.string,
        quantity: PropTypes.number
    }
});

const configDecorator = ModuleConfig({
    config: {
        k1: 'Value 1',
        k2: 'Value 2',
        viewClass: ModuleViewClass,
        ...moduleConfig
    }
});

const logDecorator = log({
    config: {
        warning: true,
        error: true,
        breakOnError:false
    }
});

@loaderDecorator
@configDecorator
@logDecorator
class MyComponent extends Component { }

然后您可以自由地将这些变量移动到您想要的任何文件,然后将它们导入到此文件中以使用它们,例如

import { loaderDecorator, configDecorator, logDecorator } from './my-decorators';

@loaderDecorator
@configDecorator
@logDecorator
class MyComponent extends Component { }

export const loaderDecorator = ModuleLoader({
    config: {
        k1: 'Value 1',
        k2: 'Value 2',
        viewClass: ModuleViewClass,
        ...moduleConfig
    },

    propTypes: {
        name: PropTypes.string.isRequired,
        age: PropTypes.number,
        address: PropTypes.string,
        quantity: PropTypes.number
    }
});

export const configDecorator = ModuleConfig({
    config: {
        k1: 'Value 1',
        k2: 'Value 2',
        viewClass: ModuleViewClass,
        ...moduleConfig
    }
});

export const logDecorator = log({
    config: {
        warning: true,
        error: true,
        breakOnError:false
    }
});