为什么我们需要在 Redux 中创建自定义中间件作为柯里化函数

IT技术 reactjs redux
2021-05-12 12:10:59

我是 Redux 的新手,正在学习如何为 React 应用程序创建中间件。关于创建自定义中间件作为CURRIED函数的问题,即为什么要currying?在创建中间件的上下文中柯里化有什么好处。也就是说,与其写const middleware = store=>next=>action=>{}为什么不写const middleware = (store,next,action)=>{}

3个回答

为什么要咖喱

实际上 Currying 试图通过使用不可变数据和纯(无副作用)函数来最小化程序状态的更改次数,称为副作用。当您想编写可以轻松重用和配置的小代码module时,柯里化很有帮助,以避免在部分应用程序中频繁调用具有相同参数的函数。

在中间件的上下文中柯里化的好处

通过使用柯里化,redux 基本上为你提供了三个钩子函数:

  • const firstFunction = logger(store)
  • const secondFunction = firstFunction(next)
  • const thirdFunction = secondFunction(action)

现在,根据不同的场景,上述每个功能都有自己的用途。Store 已经在第一个函数中创建,而第二个函数为您提供下一个中间件,在第三个函数中我们可以对前一个中间件的结果操作做一些事情。

Redux 的合著者 Dan Abramov 也回答了这个问题。你可以在这里查看他的想法

这是因为compose 的工作方式。

假设我有 2 个函数:plus2 和 times3 然后我可以将它们组合成:

const plus2Times3 = compose(plus2,times3);
plus2Times3(1);//(1+2)*3=9
plus2Times3(2);//(2+2)*3=12

compose 对 plus2 和 times3 做了什么: (...arg)=>times3(...plus2(...arg))

用简单的函数很难理解,但是柯里化函数呢?

所有中间件函数都收到相同的状态,因此如果我有一组中间件函数,我可以执行以下操作:

//middewares is [store=>next=>action=>next(action),store=>next=>action=>next(action)]
const mw = middlewares.map(fn=>fn({getState,dispatch}));
//mw is [next=>action=>next(action),next=>action=>next(action)]

现在我有一个函数数组,next=>action=>next(action)其中 next 是一个执行操作的函数。

因此,如果我提供next=>action=>next(action)下一个函数,我会得到一个函数,下一个函数:action=>does something. 这意味着 redux 可以使用 compose 从一组函数中创建一个函数:

const middeware = compose(middlewares.map(fn=>fn({getState,dispatch}));
//middeware is now next=>action=>do something
//redux can execute it with: middleware(reducer)(action)

是一个自我编写的 redux 与 react-redux 相结合的示例,它展示了如何使用 compose 从一系列中间件函数中创建一个函数。

下面是一些代码来演示如何轻松组合中间件功能:

Redux 可以为中间件选择任何签名,只要它有 store、next 和 action。以下示例与前一个示例大致相同,但将中间件函数映射到可以组合的内容:

好的,我会尽力澄清你的困惑。首先我们了解中间件的用途

中间件是您可以在接收请求的框架和生成响应的框架之间放置的一些代码

因此,由于柯里化允许您从另一个函数返回一个函数,您可以通过这种方式看到它,在将某些内容提取到框架之前,我们想做一些额外的操作,所以如果按照您的建议我们这样做

const middleware = (store,next,action)=>{}

我们直接调用框架代码,currying 允许我们中断并做我们的事情

希望能帮助到你