链接或组合多个“修补程序”的好方法吗?

时间:2018-07-23 00:34:44

标签: javascript reactjs

这是React中非常常见的模式,我们在其中“修补”一个组件,它将接收自定义属性:

export default gimmeMahProps(someRandomSettings)(MyComponent);

示例:

// Redux
connect(stateMapper, dispatchMapper)(MyComponent);

// Material UI
withStyles(myStyles)(MyComponent);

当我们拥有越来越多的这些功能时,这会变得很混乱:

// messy nested function calls with only two of those patchers
export default connect(stateMapper, dispatchMapper)(withStyles(myStyles)(MyComponent));

这是我现在正在做的,以避免出现嵌套的函数调用金字塔:

export default [
    connect(stateMapper, dispatchMapper),
    withStyles(myStyles)
].reduce((comp, patcher) => patcher(comp), MyComponent);  // kind of a hack

更具可读性,但是我正在寻找一种更简单的方法将它们链接或组合在一起。也许我缺少一些东西,但是React是否提供任何API来实现这一目标?

2 个答案:

答案 0 :(得分:2)

是的,它的名字是函数组成,是函数式编程中的基本“模式”之一(或在任何语言中,函数是一等公民,JavaScript也是如此)

您可以看看compose from redux

或者,IMO最好选择Ramda的compose(从右到左的应用程序)或pipe(从左到右的应用程序)。简而言之:

compose(fn1, fn2)(x) === fn1(fn2(x))
pipe(fn1, fn2) === fn2(fn1(x))

您的丑陋代码示例可以用这种方式编写

const enhance = pipe(
  withStyles(myStyles),
  connect(stateMapper, dispatchMapper),
)

export default enhance(MyComponent)

此外,请注意,还有一项即将推出的语言功能,称为 pipeline operator

答案 1 :(得分:1)

使用JavaScript装饰器怎么样?

@connect(stateMapper, dispatchMapper)
@withStyles(myStyles)
export default class App extends Component {
    ...

有一个名为Core Decorators的奇妙库,它提供了一些非常有用的常用装饰器,它们现在就可以使用。这些通常允许使用非常有用的通用功能(例如,方法调用的时间,弃用警告,确保值是只读的),但要使用更加简洁的装饰器语法。