我在学习redux的时候,一开始也以为很难,不少东西很难以理解,由于我是先简单学习了一遍Vue的,由于工做中用的都是react,因此Vue也忘得差很少了。写这篇文章的缘由是想帮助想入门react的小伙伴们,同时也是对本身的一个技术小总结吧。前端
react难就难在它很自由,就提供了一个JSX,而后就没有了。不过和当初React的定位也有关系,它并非一个框架,而是一个UI库。而Vue才是一个框架,由于不少事情它都帮你完成了,使用的时候仅须要知道相关的API。react
tips:能够这么粗浅的理解react,UI = fn(data)git
好了扯远了,下面开始带你入门redux吧。github
首先,在学习以前,要说明一点,react和redux没有任何关系,没有任何关系,没有任何关系;重要的事情说三遍。那redux是什么呢?是一个管理数据的仓库。编程
缘由是由于前端数据的复杂度没有人来管理,由于react当初的定位也是为了解决中大型项目,项目一旦复杂起来,须要共享的数据就会很庞大复杂。redux
在介绍核心概念以前,咱们先来了解一个东西,就是Flux。在Flux中,Facebook最先提出了一个action的概念,经过action来直接修改数据仓库store,action是一个普通的对象,用于描述要干什么。store根据不一样的action来对数据进行操做。数组
这样就会有一个问题,当业务复杂,数据庞大的时候,store的压力就不少了,因此才有了后面redux的出现,到这里,你只须要知道redux的三个核心概念就能够了。app
action:至关于页面请求等操做,分发dispatch框架
store:数据的仓库函数式编程
第一步:首先action是一个平面对象,就是一个简单的对象,必需要传type属性,类型任意,表明着你要干什么,还有一个可选属性是payload,就是请求时候的附加数据。
第二步:store接收到action的请求以后,把旧的数据state,和请求action交给reducer,让reducer来修改数据,修改完以后返回一个新的数据newState给我,以便更新数据。
明白了上图描述的redux工做流程以后,咱们须要建立一个store,由于根据上图,不论是接收action,或者是触发reducer修改数据,都是根据数据仓库的,全部咱们先要建立一个数据仓库。直接看下面代码和注释吧。
createStore 返回值是一个对象,对象包含如下几个属性
getState:获得当前的state数据
Symbol('observable'):提案,暂时用不到
tips:到这里,熟悉发布订阅模式的小伙伴,就知道其实 createStore 内部的代码原理就是使用了发布订阅模式。不熟悉发布订阅模式的小伙伴须要去了解一下。
接着咱们把action和reducer完善好
最后咱们就可使用了,结合上图的两个步骤理解
tips:最好本身手动实现一遍代码,而后按照redux工做原理两大步骤图理解一下。
根据上面redux的工做流程,有没有发现太麻烦了?的确是太麻烦了,尤为是第二步,要本身主动去使用store.dispatch,而后再往里面塞action的平面对象。那有没有方便一点的方法呢?redux提供了一个函数,bindActionCreators,加强action建立函数,让action以后自动触发dispatch。
使用起来就至关简单了,下面作一个对比
如今还有一个问题,就是仓库数据只有一个,只有一个reducer,而在实际的项目中,数据是很庞大的,有不少个reducer,那怎么来管理这么多数据呢?
咱们能够先这样解决问题
其实redux很贴心,为我么提供了至关于上面效果的一个函数,就是 combineReducers。
完善 validiteReducers 函数
使用的时候,只须要简单的导出 combineReducers 的运行结果便可,由于它返回一个总的reducer函数,能够对比一下不使用combineReducers的时候。
如今咱们基本上算是完成了一个简陋版的redux,可是在实际的业务开发中,每每须要请求数据,打印日志之类的不少附加功能,咱们就举一个简单的例子。如今有一个需求,我要打印旧数据和新数据。首先咱们分析一下需求,结合redux的工做流程,咱们知道,action必须返回一个没有反作用的平面对象,reducer必须是一个纯函数。何况action只能拿到旧数据,reducer也不行,观察发现createStore里面的能够拿,那只能在里面作手脚了。怎么作手脚呢?又不能影响原来的功能。
机智的咱们能够先这样作
其实这个就是middleware中间件的原理。并且,中间件如何运用在redux上?总不能像上面这么low的写法吧?别急,咱们一步步慢慢分析,理清楚下面这些概念
先看第五点,要使用中间件,必须调用applyMiddleware函数,将函数的返回值做为createStore的第二或第三参数,来告诉仓库,咱们建立仓库的时候,要使用中间件。假设咱们有下面三个中间件,建立仓库的时候调用applyMiddleware函数。applyMiddleware函数会倒着来运行每一个中间件。在这里你能够先无论它为何倒着来,先忽略。
而后用代码来写一遍,先书写三个中间件。
而后使用中间件
到这里,你可能会问applyMiddleware为何要倒着来运行全部的中间件,这和代码的运行逻辑有关,下面咱们就来解析一下applyMiddleware是怎么来把全部的中间件运行起来的。在介绍applyMiddleware前,咱们先来认识一下compose,它是函数组合, 函数式编程中的声明式编程,其实就是把全部的函数的功能组合到一块儿。
其实能够简单的理解成,把全部函数的功能组合成一个函数,就是compose。
有了compose以后,咱们就能够实现applyMiddleware的原理了,以下代码
到这里,咱们就知道为何applyMiddleware一开始调用的时候是反过来的了。compose函数式编程的魔法,真香!!!
至此,三个中间件就会运用在建立函数里面了,这也是为何建立函数的第二个参数能够传中间件或者默认值,createStore的完整代码应该是这样的。
只看上面的代码确定很羞涩难懂,结合下面的图片看才好理解
其实redux用applyMiddleware使用中间件就是一个洋葱模型,用到切洋葱(redux)的时候真想哭(学redux),吃洋葱(react+redux)的时候,真香。
/**
那为何要放在第一个呢?
tips:再仔细想下整个流程,最后跟着思路码一边。
前面咱们都是在讲redux怎么管理数据,那咱们的组件怎么使用数据呢?
假设咱们都定义好了action、reducer,而且建立好了store。
那么接下来咱们能够这样拿到数据(Users组件拿),直接定义两个方法,把须要的数据映射进去。
仔细看mapStateToProps、mapDispatchToProps。咱们把须要的数据直接经过导入store,传进去就完事了。同时订阅一下this.setState就能够完成改变数据就刷新界面的效果。
redux仍是很贴心的,哪里麻烦就出哪里的API,这时候就可使用react-redux中的 connect 方法了。首先你要理解下面的笔记,或者能够直接去看相关的API文档。
有了connect以后代码就能够变得很简单了。直接导出就完事了
redux其实使用不难,可是理解原理,解析原理代码是很是绕的,必定要多写几遍代码理解才能真的学会使用redux。
这里提供我学习redux源码的全部代码笔记,有兴趣的小伙伴能够clone下来研究学习。
github:github.com/huangruitia…