Redux中间件解析

Redux中间件解析

1. Redux的工作原理

redux对于我们进行全局的状态管理是非常有用的,我们可以省去很多力气去管理组件间的状态传递等等

  1. redux中的核心api和作用

    image-20210722191935305

redux解决的真正问题是React组件间的状态共享状态管理问题,通过以上的6个核心api我们便能管理复杂的状态,并能监听和追溯状态的改动,redux的工作机制如下

image-20210722192110813

当我们要去改变状态的时候,我们会dispatch一个action(一个普通的js对象),我们最终的状态改变是在reducer中进行的,reducer会根据原来的state和action来产生一个新的state,这样store中的状态改变了之后又会将数据展示到页面上,完成了我们的状态管理。

2. redux中间件

中间件是一个非常好用的东西,我们回顾我们上面讲到的流程,如果我们要进行一些其它的事情,比如对于每一次状态改变都打印日志,或者说我们可以进行异步的action。怎么做呢,首先action是一个对象,我们肯定不好在这里做拓展,然后reducer又是一个纯函数,我们也不方便在这里做有side effect的事情,所以我们唯一可以做处理的就是dispacth。redux中间件的主要思想就是会重写之前的dispatch,然后会让这个dispatch做我们想要做的事。我们使用中间件的时候都会这样使用

import { createStore, applyMiddleware } from 'redux';
import reducers from './reducers';

const middlewares = applyMiddleware(middleware1, middleware2);
const store = createStore(reducers, middlewares);

上面有一个applyMiddleware方法,我们看一下这个方法的源代码

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
        `Dispatching while constructing your middleware is not allowed. ` +
          `Other middleware would not be applied to this dispatch.`
      )
    }

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    
    // 参数一,传入原始的getState和dispatch
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    // 参数二: 传入中间件链上的上一个dispatch,最开始的传入原始的dispatch
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

解读一下:以中间件thunk为例

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => (next) => (action) => {
     // 这边可以让我们dispatch一个函数,我们可以在这个函数里面执行副作用的事情
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    // 使用上一个dispatch来调用我们传进去的action
    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

发现一个中间件的形式是这样的

({ dispatch, getState }) => (next) => (action) => {}

有三个参数,前两个参数都是在applyMiddleware中调用的,最后一个参数就是action,也就是我们调用dispatch的时候传入的。顺便提一下注入第二个参数的时候引入的compose函数,源码如下

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }
  
  if (funcs.length === 1) {
    return funcs[0]
  }
  
  // 链式调用中间件,可以看成一个洋葱模型
  return funcs.reduce(function(a, b) {
    return function (...args) {
      return a(b(...args))
    }
  })
}

其实就是一个reduce函数,也就是将上一个函数传递给下一个函数使用,也就实现了我们之前所说的第二个参数就是上一个中间件执行后的dispatch。这个可以参考下MDN上的reduce中提到的这个功能性管道函数

image-20210722193930721

以上就是redux和中间件的主要思想了,精妙的很

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值