这是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来实现这一目标?
答案 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的奇妙库,它提供了一些非常有用的常用装饰器,它们现在就可以使用。这些通常允许使用非常有用的通用功能(例如,方法调用的时间,弃用警告,确保值是只读的),但要使用更加简洁的装饰器语法。