手机版

简单了解react-thunk中间件

时间:2021-08-24 来源:互联网 编辑:宝哥软件园 浏览:

前言

刚来公司的时候,对thunk中间件在react项目中的作用了解不多。最近决定好好学习。鉴于我第一次写博客,我假设读者已经掌握了redux的一些基本用法。如果有错误,请指出来。非常感谢!

首先,简要回顾一下redux工作流

画面不太好,见谅;

对于reactUI组件,有两个数据源,一个是用户触发的动作,比如点击事件、提交表单、输入操作;另一种是组件的主动数据更新,比如获取页面的初始数据,子组件接受父组件道具的变化来更新视图操作;

如图所示,无论是哪种数据操作,都会发送一个动作进行查看

状态更新

众所周知,在redux中,每次更新Store都会对应一个新的视图,Store中数据的更新依赖于动作——3354Store的触发。调度(操作)将根据初始化期间在createStore中注入的缩减器计算新状态。

从“reducx”//reducer计算状态的纯函数//initialstate的初始化数据//中导入{createstore},在增强器中间件中使用createstore (reducers,initial state,enhances)操作并扩展插件

对于组件输入操作(如点击事件),store.dispatch(操作)可以绑定到组件

const store=CreateStore(reductor);const TodoList=({ state,someaactioncreator })=(Ul { state . map(someState=Todo key={ someState . somedata } onClick={()=store . dispatch(someaactioncreator(state . somedata))}//Ul)或者通过connect方法,从组件的道具中获取dispatch方法并发送一个操作

//将状态注入组件的道具//注意这里的状态是指redux管理的数据,每个视图的状态对应//一个唯一的状态;//状态的集合是redux=store=({ state : store . state })管理的storeconst mapstatetoprops动作被注入组件的道具中。const mapdispatcherops=dispatch=({ actions : state=dispatch(action creators(state))})Export default connect(mapstatetorops,mapdispatchetoprops) (todolist)然后组件绑定事件就可以改成这个了(action creators用于生成action,参考官方链接https://redux.js.org/basics/actions)

Const todolist=({state,actions})=(` ul {state。map(some state=todokey={ some state。some data } onclick={()=actions(some state。有些数据)}//ul `)然后问题来了。dispatch同步执行reducers但是如果click事件请求一个结果,在更新视图之前需要等待结果响应吗?应该怎么做?

因此,redux引入了thunk中间件和扩展动作

##thunk中间件解决了什么问题?

随着thunk插件的引入,我们可以在actionCreators内部编写逻辑来处理请求结果。而不是简单地返回一个动作对象。

//在介绍之前,让nextto id=0导出const add todo=Text=({ type : ' add _ todo ',id: nextto id,Text }) //让nextto id=0导出const add todo=Text=({ return async dispatch={//做某事,Request wait Request()dispatch({ type : ' add _ todo ',id:nxtodoid,text})})如何使用Thunk中间件

从“redux”导入{ applyMiddleware,CreateStore };从“redux-thunk”导入thunk;const store=createStore(reducer,applyMiddleware(thunk));CreateStore实际上可以接受三个参数。第二个参数preloadedState一般用作整个应用程序的初始化数据。如果传入此参数,applyMiddleware将被视为第三个参数

const store=createStore(reducer,initialState,applyMiddleware(thunk));中间件应该放在applyMiddleware中。如果您想要添加中间件,您可以依次添加它,但是您应该遵循文档定义的顺序

const store=createStore(reductor,initialState,applyMiddleware(thunk,middleware1,中间件2));源码解读

也许你会奇怪,为什么使用的时候要按照上面的写法,那我们就一起看下方法的实现

首先是创建存储的参数顺序

函数创建存储(缩减器、预加载状态、增强器){ var _ ref 2;if(预加载状态的类型==' function '增强器的类型==' undefined '){增强器=预加载状态;预加载状态=未定义;}如果(增强剂的类型!=='undefined') { if(增强器的类型!==' function '){ 0引发新错误('要求增强器是一个函数');}返回增强器(createStore)(减速器,预载状态);}如果(减速器类型!=='函数'){抛出新的错误('期望缩减器是一个函数。');}第一个判断已经告诉了我们答案,参数的类型检验结果决定了顺序

applyMiddleware是干什么用的函数applyMiddleware(){ for(var _ len=参数。长度,中间件=Array(_ len),_ key=0;_ key _ len_ key){中间件[_ key]=参数[_ key];}返回函数(CreateStore){ 0返回函数(){ for (var _len2=arguments.length,args=Array(_len2),_ key 2=0;_ key2 _ len2_key2 ) { args[_key2]=参数[_ key 2];} var store=createStore.apply(未定义,参数);var _ dispatch=函数dispatch(){ 0抛出新错误('不允许在构建中间件时进行调度。'其他中间件不会应用于此调度。);};var middlewareAPI={ getstate : store。getstate,dispatch :函数dispatch(){ return _ dispatch。应用(未定义,参数);} };var链=中间件。map(函数(中间件){返回中间件(中间件API);});_dispatch=compose.apply(未定义,连锁)(商店。派遣);return _extends({},store,{ dispatch : _ dispatch });};};}代码不多,而且非常清晰:

1、应用管理软件顾名思义,用于调用各种中间件;2、应用管理软件执行后,将所有入参中间件存入一个数组,并且返回一个闭包(闭包的概念不做累述)3、闭包接受一个创建存储作为入参并且执行后返回下一个闭包,createStore这个入参有没有很眼熟,没错,就是回家的的创建存储。

返回结果

返回将所有中间件串联存入的派遣,执行时从右向左执行,第一次的执行结果会返回给一下个,依次类推。

如何实现每个中间件串联执行

_dispatch=compose.apply(未定义,链),使用了一个构成函数,调用之后就可以将所有中间件串联起来,那么构成又是如何实现的呢?

精华所在

函数compose(){ for(var _ len=参数。长度,funcs=Array(_len),_ key=0;_ key _ len_key ) { funcs[_key]=参数[_ key];} if(funcs。length===0){ return函数(arg){ return arg;};} if(funcs。length===1){ return funcs[0];}返回funcs.reduce(函数(a,b){ return function(){ return a(b . apply(未定义,参数));};});}个人认为这个构成函数是整个回家的中非常亮眼的部分,短短几行代码,就完成了一个核心功能的扩展,是责任链设计模式的经典体现。

也我们也可以使用这个构成方法对applyMiddleware进行扩展

让dev tools=()=noop={控制台。日志(noop);返回noop///CreateStore };常数增强器=[ applyMiddleware(.中间件),dev tools()];createStore(reducers,initialState,compose(.增强剂));然后回来,我们就明白了创建存储中的设计

//如果存在中间件参数,那么将会得到一个经过改装的dispatch//return _extends({},store,{ dispatch : _ dispatch });如果(增强剂的类型!=='undefined') { if(增强器的类型!==' function '){ 0引发新错误('要求增强器是一个函数');}返回增强器(createStore)(减速器,预载状态);}派遣经过了怎样的改装

如上已经说过,撰写会将传入的函数数组从右向左串联执行

compose.apply(未定义,连锁)(store . dispatch);Thunk将接受上一个中间件的执行结果并继续执行,最后在createState中返回一个修改后的派单。接下来,我只需要看看thunk是如何实现的,就能理解整个中间件的原理:

函数createthunk middleware(extra argument){ return function(_ ref){ var dispatch=_ ref . dispatch,getState=_ ref.getStateReturn function (next) {//最终的dispatch //next是接收到的store.dispatch参数,是之前中间件修改的dispatch return function(action){ if(action的类型==' function '){ return action(dispatch,getstate,extra argument);}返回next(操作);};};};} var thunk=createthunk middleware();thunk . withextrault=createthunk middleware;导出默认thunk代码也被细化,修改后的派单进入接受的数据类型:

1.如果它不是一个函数,不要处理它。将动作传递给下一个中间件,最后根据传入的动作计算相应的reducers(开始时自动执行)——3354 store.dispatch(动作)。2.函数类型的动作将自动触发函数,并传入store.dispatch。

摘要

结合开头介绍的thunk的用法,可以了解thunk的原理。我们可以在actionCreators中返回一个函数,然后在函数中编写一些异步操作。异步操作完成后,我们将向商店发送一个操作通知,通过传入的商店更新状态

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:简单了解react-thunk中间件是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。