听过Redux很久了,不过真的开始学大概在一个月前,学会Redux以后我用一周多的时间重构了以前纯React写的一个小项目。学习的过程当中心态变化很大,可是最终真的感受若是再写复杂一点的项目,我应该不再会直接用state管理全部状态了。Redux真的刷新了个人状态管理观。javascript
本文的写做目的在于让那些一直在使用React,可是尚未使用Redux管理复杂应用状态的同窗了解Redux的核心思想并可以更加平滑的学习使用Redux。html
快双十一了,忽然想到一个比喻来解释为何会有React这类框架的存在,为何咱们要使用Redux,话说之前使用jQuery不也挺快乐的嘛。前端
想一想现代物流系统发展的不一样阶段,咱们寄一件东西的过程,java
没有物流系统时:react
打包准备好要送出去的东西;git
出门乘车到达朋友家,把东西送给朋友;github
很直接很方便,很费时间,送东西的距离有限(同城?);编程
出现了各大物流公司时:redux
打包准备好要送出去的东西;api
出门到距离家最近的物流公司,填写物品,收件人等基本信息;
物流公司替你送物品到你的朋友处,本身能够回家作别的事情了;
多了一个中介,要付必定的运送成本,可是东西能够送到远在几千千米以外的其它人了,用一点点钱节约了本身宝贵的时间,完成了之前咱们不可能作的事情;
没错,没有物流系统时对应的就是之前使用jQuery的前端阶段,作一件事情很直接,若是只是送快递给一个特别近的人,那固然是很是方便。就算你要从北京送一个东西到上海,在这个阶段你也能够实现,可是须要付出的代价就太大了。
而出现了各大物流公司对应的就是使用React等框架的阶段,学习React须要付出成本,若是你只须要作简单的事情(好比说你想把东西送给你的邻居),那使用此类框架其实显得特别累赘,把简单的事情复杂化了,可是若是你想作复杂一点的事情(同时寄礼物给三个不一样城市的人),那么选择快递公司是不会错的。
那么React和Redux的关系又该如何理解呢?
我以为咱们能够把React
好比为一家自建快递系统的公司(京东?),在必定范围内,它的快递系统已经足够好了(部分一二线城市一天内直达),可是要管理这个日益复杂的快递系统,须要公司付出巨大的成本。
Redux
能够看作业内最好的第三方快递系统(顺丰?),使用它比较贵(学习成本稍微有点高),可是他到达全国主要城市都会特别快,若是你是一个电商老板,采用这个第三方物流系统以后,你只须要关注于本身的货物,几乎不用再去关心物流怎么办了。
不一样于顺丰每一次寄货都要那么高的价格,redux是一个学习一次,就能够免费寄货的优秀第三方快递系统,那咱们固然要解散本身的物流公司来采用这个第三方的选择的。不过话说回来,学习是须要有成本的,因此是直接使用React仍是学习Redux再使用,这是你一个你须要依据你本身项目的实际状况做出选择的事情。
不过这个例子可能并不足够合适,Redux作的不只仅是管理原来React里state里面的状态。Redux其实能够接管咱们的app里全部的数据。接下来咱们具体看看Redux究竟作了什么。
咱们经常听到一种说法,“Redux是一个很是好的状态管理器”,那究竟什么是状态呢。
想一想咱们平时看的网页,app,或者任何其它和咱们有交互的东西,咱们感受到交互的发生是由于界面依据咱们的行为做出了反馈,界面全部的改变,其实均可以看做是状态的改变,或者说界面会改变是由于咱们的某个行为(事件)(click
,drag
,move
...)触发了某个函数,函数形成了状态的改变,进而改变了界面。
如此看来,不管是显示隐藏这种可见的状态,仍是从服务器获取更多的数据,这些均可以看作是状态,而这些状态就是咱们的Redux要管理的。
换一个可能比较专业一点的说法吧,状态包括
API State;(数据)
UI State;(UI的表现形式)
为了更好的展现Redux的好,咱们回顾一下前端的状态管理史(称为史其实并不合适,如下三种模式如今都有大量人在使用)。
中古
jQuery 时期
咱们使用诸如$(element).addClass('active')
这样的语句来改变状态;
对简单的应用来讲,这样写简单明了,可是状态一多一复杂就乱了,并不存在一个专门管理状态的地方;
近代
React内部管理状态时期
咱们引入了state
来管理组件状态,界面想显示不一样的样子,咱们经过各类函数来改变state
来实现
已经存在一个专门管理状态的state
(对象,数组)了,对大部分应用来讲,用state
来管理状态已经足够了,可是应用复杂了会使得状态
现代
引入Redux等状态管理机制时期;
redux使用一个store
来全局管理各类状态,提供一些不算复杂的api来专门管理状态;
能够管理更加复杂的状态,经过redux的管理,状态的改变变得更加清晰,可预测,redux
中的状态是一个只读属性,经过必定的方法,能够回到已经经历过的某个状态(时间旅行);
(这里没有说到MVC等机制有兴趣的同窗能够看这篇文章作进一步对比了解,基本观点是MVC当然很好,可是配合React使用时,性价比不是那么高了。)
上面已经说了Redux管理状态特别好,那Redux到底是如何管理状态的呢?状态分为UI State 和 API State,Redux针对这两部分也提供了两种方法
为改变已有的状态提供了方案;
为异步获取新的数据提供了方案;
仍是用图片来讲明更加清楚
下图说明了Redux和React的状态流分别是怎么样的;
下图说明了使用Redux管理状态为何是可预测的
Redux的数据是如何流动的其实也是理解Redux的好处的关键部分之一,简单来讲每一个事件会发送一个action,action经过dispatch触发reduce,直接依据旧的state生成一个新state替代最顶层的store里面原有的state。
有一篇文章以漫画的形式把这个讲的特别透A Cartoon intro to redux
说了这么多使用redux管理状态的好处,可是你看到这里可能依旧不知道如何使用redux
,不要着急,我和你分享个人Redux学习经验。
若是你已经能很熟练的使用React,我以为学习Redux须要了解的基础知识,你应该都已经了解了。具体说来主要有如下内容;
React(Redux是flux架构的实现,虽然其也能够配合其它框架使用,可是它和React可能仍是更配一些吧);
基础的ES6知识(Redux重视函数式编程,会使得编程的结构看起来更加简洁);
用了ES6(甚至ES7)固然免不了要学习使用Webpack,Babel等;
还有一点,我以为学习编程应该不怕折腾,使用Redux管理一个状态可能须要改好几个文件里的代码才能实现,编程再也不显得那么直接(好比 经过connect.js
调用action.js
里的某个action
,并依据这个action
触发reducer.js
里面的某个reducer
函数依据现有的state
,建立一个新的state
),redux把一些操做给抽象化了,若是思惟没有跟着改变,会让人有一种redux文档里面的东西我都看懂了,可是我怎么就是编不出来呢?那种痛苦的感受。
网上关于Redux的教程特别多了(官方文档写的特别好),学习新概念是比较恼人的一个过程,因此我仍是会对Redux提供的api作一个简洁的描述,而后我会把我这段时间看过的我以为比较好的文章的连接放在下面以供你们参考。
state
:app中的状态存放的地方,而且state是只读的,不一样于React,Redux中state的更改,实际上是建立了一个全新的state;
action
:是一个对象,做用和他的名字同样,用来代表,你想要作的那件事情,该对象的属性type,用来标记,你要作的事情;
reducer
:是一个函数,接收当前state,和一个action做为参数,依据action基于当前的state
生成新的state
;
dispatch
:推送某个action
给reducer
;
action creater
:一个建立action
的函数,返回一个action
对象;
异步action
:返回一个函数,和中间件配合能够很容易的实现异步操做;
store
:能够理解为state
的家,全局只有一个,有如下方法
getState()
:获取当前的state树;
dispatch(action)
:触发一个action,建立state;
subscribe(listener)
:
replaceReducer(nextReducer)
combineRedecers(reducers)
:当咱们的应用比较复杂的时候,咱们可能会分开写好几个reducer
,这个函数的做用就是把这些单独的reduce合并为一个大的reduce,须要注意的是咱们的state的结构和咱们的各个reducer
是一一对应的。
applyMiddleware(...middlewares)
:告诉redux咱们会用到那些中间件,好比说要用到基础的异步,咱们会用到thunk中间件;
let store = createStore( comReducer, applyMiddleware(thunk) );
bindActionCreators(actionCreators, dispatch)
:绑定actionCreator
和dispatch
以供直接使用;
redux只是管理状态的一种方法,真的用在React里,使用做者提供的一个工具react-redux
会更加方便,其api很简单,主要有如下几个;
<Provider store>
,嵌套在React组件的最外层,所以能够把state传给全部的组件(利用了React的context
);
把React组件分为容器组件和UI组件两类,容器组件管理逻辑,UI组件管理显示效果两者经过connect
方法链接,容器组件通常由UI组件依据connect
生成;
mapStateToProps()
,存在于容器组件中,针对UI组件的各状态(依据state
,或者父组件的props
)生成;
mapDispatchToProps()
,存在于容器组件中,针对UI组件中的各可能改变state的事件定义的一系列的函数,依据props
传给UI组件;
Redux还有一个很是酷的工具,让咱们能够实时看到当前的state,使用redux不可不用啊。
酷酷的工具redux devtools
在弄懂了一些关键的核心概念之后,若是仍是不知道怎么写,就模仿官方给的多个例子针对本身的需求敲写一次吧。模仿了两个例子就确定明白了。
Redux也有本身的小生态,理解的一些技术辅助Redux更加方便的实现状态管理,其中有一些是下一步我特别想了解的好比说immutable-js,reselect,normalizr,固然由于学习了Redux,因此我也想对函数式编程作进一步理解,以前找到了一本很是好的关于函数式编程的书mostly-adequate-guide,分享给你们,你们一块儿学习。