redux原理解析,看这篇就够了,移动前端开发前景

本文详细解析了Redux中的dispatch函数、reducer的作用以及如何通过createStore创建store。重点介绍了中间件如redux-thunk的实现原理和applyMiddleware函数在处理异步逻辑中的作用。
摘要由CSDN通过智能技术生成

function dispatch(action) {

// currentReducer --> combination函数

currentState = currentReducer(currentState, action)

}

// 初始化调用dispatch,创建初始state

dispatch({ type: ActionTypes.INIT })

const store = ({

dispatch: dispatch,

subscribe,s

getState,

replaceReducer,

}

return store

}

// 源码地址:https://github.com/reduxjs/redux/blob/master/src/createStore.ts#L60

reducer就是传入的combination函数,preloadedState是初始化的state(没有太大的作用),enhancer是中间件,没有第三个参数enhancer的情况下,同时第二个参数preloadedState是一个函数,preloadedState被赋值给enhancer。

调用dispatch函数初始化,currentReducer即是传入combination函数,就向上文提到的,调用combination函数实际就是循环调用reducer函数。所有的state对象,被挂载在内部变量currentState上。存在中间件enhancer时,将createStore传入中间件函数,调用enhancer函数,return结束,这个下文会继续讲到。

创建的store对象,暴露出的方法如下:

const store = ({

// 分发 action,这是触发 state 变化的惟一途径。

dispatch: dispatch as Dispatch,

// 变化监听

subscribe,

// 获取store下的 全部state

getState,

// 替换 store 当前用来计算 state 的 reducer

replaceReducer

}

return store

dispatch函数触发action,调用reducer函数,修改state。subscribe函数可以监听变化state的变化。getState函数获取全部state。replaceReducer函数替换用来计算state的reducer函数。

通过combineReducers函数合并reducer函数,返回一个新的函数combination(这个函数负责循环遍历运行reducer函数,返回全部state)。将这个新函数作为参数传入createStore函数,函数内部通过dispatch,初始化运行传入的combination,state生成,返回store对象

redux中间件


最好把上面看懂之后,再看中间件部分!!下面对中间件进行分析:

redux-thunk只是redux中间件的一种,也是比较常见的中间件。redux-thunk库允许你编写与store交互的异步逻辑。

import thunkMiddleware from ‘redux-thunk’

const reducer = combineReducers({

home: homeNumber,

number: addNumber

})

const store = createStore(

reducer,

applyMiddleware(

thunkMiddleware, // 异步支持

)

)

createStore函数支持三个参数,如果第二个参数preloadedState是一个函数,而没有第三个参数enhancer的话,preloadedState会被赋值给enhancer

下面会以redux-thunk中间件作为例子,下面就是thunkMiddleware函数核心的代码:

// 部分转为ES5代码,运行middleware函数会返回一个新的函数,如下:

return ({ dispatch, getState }) => {

// next实际就是传入的dispatch

return function (next) {

return function (action) {

// redux-thunk核心

if (typeof action === ‘function’) {

return action(dispatch, getState, extraArgument);

}

return next(action);

};

};

}

// 源码地址:https://github.com/reduxjs/redux-thunk/blob/master/src/index.js

redux-thunk库内部源码非常的简单,github: redux-thunk 源码 ,允许action是一个函数,同时支持参数传递,否则调用方法不变。

applyMiddleware函数

// 中间件调用

return enhancer(createStore)(reducer, preloadedState)

// 等价于

return applyMiddleware(

thunkMiddleware,

)(createStore)(reducer, preloadedState)

redux的中间件,从applyMiddleware函数开始,它主要的目的就是为了处理store的dispatch函数

// 支持多个中间件传入

export default function applyMiddleware(…middlewares) {

return (createStore) => (reducer, …args) => {

// 创建 store

const store = createStore(reducer, …args)

const middlewareAPI = {

getState: store.getState,

dispatch: (action, …args) => dispatch(action, …args)

}

// 遍历运行中间件函数,将middlewareAPI作为参数传入

// middleware对应上面的redux-thunk库核心代码,当然也支持多个中间件

const chain = middlewares.map(middleware => middleware(middlewareAPI))

// 核心:将所有中间件传入到compose中,返回一个新的dispatch

dispatch = compose(…chain)(store.dispatch)

// 照常返回一个store对象,dispatch已经被处理过了

return {

…store,

dispatch

}

}

}

// 源码地址:https://github.com/reduxjs/redux/blob/master/src/applyMiddleware.ts#L55

applyMiddleware函数接收多个middlewares参数,返回一个store对象。通过createStore创建store对象,middlewareAPI对象挂载getState和dispatch,循环middlewares中间件,将middlewareAPI作为参数传入每个中间件。遍历结束以后,拿到了一个包含所有中间件新返回函数的一个数组,将其赋值给变量chain。

// 遍历之后chain的值,这里只是拿redux-thunk库作为例子

// next 就是 dispatch

chain = [function (next) {

return function (action) {

if (typeof action === ‘function’) { // redux-thunk核心

return action(dispatch, getState, extraArgument);

}

return next(action);

};

}, …更多中间件]

compose函数

// 数组chain 保存所有中间件新返回函数

dispatch = compose(…chain)(store.dispatch)

compose的主要作用就是运行所有中间件函数后,返回一个经过处理的dispatch函数。

// compose函数

return chain.reduce((a, b) =>{

return (…args)=> {

return a(b(…args))

}

}

chain是保存中间件函数的数组,具体的内部结构参见上面???,下面来分析一下compose函数的调用逻辑。

// chain 类比为 [fn1, fn2, fn3, fn4]

[fn1, fn2, fn3, fn4].reduce((a, b) =>{

return (…args)=> {

return a(b(…args))

}

}

调用过程如下:

| 循环 | a值 | b值 | 返回的值 |

| — | — | — | — |

| 第一轮循环 | fn1 | fn2 | (…args)=> fn1(fn2(…args)) |

| 第二轮循环 | (…args)=> fn1(fn2(…args)) | fn3 | (…args)=> fn1(fn2(fn3(…args))) |

| 第三轮循环 | (…args)=> fn1(fn2(fn3(…args))) | fn4 | (…args)=> fn1(fn2(fn3(fn4(…args)))) |

经过 compose 处理过之后, 最后的返回值就是 (...args) => fn1(fn2(fn3(fn4(...args)))),这个的arg就是 store.dispatch函数。最后将返回函数赋值给dispatch,就是我们需要的dispatch函数了。而如果只有一个中间件的话,就会直接返回了。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后:

总结来说,面试成功=基础知识+项目经验+表达技巧+运气。我们无法控制运气,但是我们可以在别的地方花更多时间,每个环节都提前做好准备。

面试一方面是为了找到工作,升职加薪,另一方面也是对于自我能力的考察。能够面试成功不仅仅是来自面试前的临时抱佛脚,更重要的是在平时学习和工作中不断积累和坚持,把每个知识点、每一次项目开发、每次遇到的难点知识,做好积累,实践和总结。

点击这里领取Web前端开发经典面试题

,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后:

总结来说,面试成功=基础知识+项目经验+表达技巧+运气。我们无法控制运气,但是我们可以在别的地方花更多时间,每个环节都提前做好准备。

面试一方面是为了找到工作,升职加薪,另一方面也是对于自我能力的考察。能够面试成功不仅仅是来自面试前的临时抱佛脚,更重要的是在平时学习和工作中不断积累和坚持,把每个知识点、每一次项目开发、每次遇到的难点知识,做好积累,实践和总结。

点击这里领取Web前端开发经典面试题

  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值