为什么我们需要在 Redux 中创建自定义中间件作为柯里化函数 [英] Why do we need to create custom middleware as curried function in Redux

查看:32
本文介绍了为什么我们需要在 Redux 中创建自定义中间件作为柯里化函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Redux and was learning how to create middleware for React app. The question I would like to ask on the creation of custom middleware as CURRIED function, that is, why currying? what is the benefit of currying in the context of the creation of middleware. That is, instead of writing const middleware = store=>next=>action=>{} why not write const middleware = (store,next,action)=>{}.

推荐答案

这是因为 compose 有效.

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

Say I have 2 functions: plus2 and times3 then I can compose them with:

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

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

What compose did with plus2 and times3 is: (...arg)=>times3(...plus2(...arg))

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

Difficult enough to understand with simple functions but how about curried functions?

所有中间件函数都收到相同的状态,所以如果我有一组中间件函数,我可以这样做:

All middle ware functions receive the same state so if I have an array of middleware functions I can do:

//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 是一个执行动作的函数.

Now I have an array of functions that are next=>action=>next(action) where next is a function that takes an action.

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

So if I provide next=>action=>next(action) with a next function I get a function that is a next function: action=>does something. This means redux can use compose to create one function out of an array of functions:

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 从一系列中间件函数中创建一个函数.

Here is an example of a self written redux combined with react-redux that shows how compose is used to create one function out of an array of middleware functions.

以下是一些代码,用于演示如何轻松组合中间件功能:

Here is some code to demonstrate how to easily compose middleware functions:

//implementation of compose is very simple, I added taking
//  out anything that isn't a function
const compose = (...functions) => {
  return (
    functions
      //take out non functions
      .filter(e => typeof e === 'function')
      .reduce((result, fn) => {
        return (...args) => result(fn(...args));
      })
  );
};
const middeWares = [
  store => next => action => {
    console.log('1', action);
    next({ ...action, counter: action.counter + 1 });
  },
  store => next => action => {
    console.log('2', action);
    next({ ...action, counter: action.counter + 1 });
  },
  store => next => action => {
    console.log('3', action);
    next({ ...action, counter: action.counter + 1 });
  },
];
//just pass in 88 as store, we don't use store
const middleWare = compose(...middeWares.map(x => x(88)));

//executing the middleware
//pass in id function as next function (probably reducer in redux)
middleWare(x=>x)({counter:86});

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

Redux could have chosen for any signature for middle ware as long as it has store, next and action. The following example is mostly the same as the previous one but maps middleware functions to something that can be composed:

const compose = (...functions) => {
  return (
    functions
      //take out non functions
      .filter(e => typeof e === 'function')
      .reduce((result, fn) => {
        return (...args) => result(fn(...args));
      })
  );
};
//middleware could also have (action,next,store) signature
const middeWares = [
  (action,next,store) => {
    console.log('1', action);
    next({ ...action, counter: action.counter + 1 });
  },
  (action,next,store) => {
    console.log('2', action);
    next({ ...action, counter: action.counter + 1 });
  },
  (action,next,store) => {
    console.log('3', action);
    next({ ...action, counter: action.counter + 1 });
  },
];
//using 88 for store, we can map the middleware to s=>n=>a=>...
const middleWare = compose(...middeWares.map(x => n=>a=>x(a,n,88)));
//pass in id function as next function (could be dispatch or reducer)
//  depending on how redux is written
middleWare(x=>x)({counter:86});

这篇关于为什么我们需要在 Redux 中创建自定义中间件作为柯里化函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆