上周利用业余的时间看了看Redux,刚开始有点不适应,一下在有了Action、Reducer、Store和Middleware这么多新的概念。html
通过一些了解以后,发现Redux的单向数据里的模式仍是比较容易理解的,结合着Redux的单向数据流模型,不少概念就比较清晰了。react
下面就按照本身的理解整理出了Redux中相关的内容,若是你也刚开始学习Redux,但愿能给你一个直观的认识。git
首先,先看看第一张图,图中展现了Redux的单向数据流,以及Action、Reducer和Store这三个核心概念。github
下面就围绕上图,非别介绍Action、Reducer和Store这三个概念。redux
Action是一个对象,用来表明全部会引发状态(state)变化的行为(例如服务端的响应,页面上的用户操做)。promise
假如咱们要实现一个任务管理系统,那么添加任务的Action对象就会是下面的形式:app
{ type: 'ADD_TASK', name: 'Read ES6 spec', category: 'Reading' }
Action对象是行为的描述,通常都会包含下面的信息:框架
Action经过Action建立函数(Action Creator)来建立,Action Creator是一个函数,最终返回一个Action对象。异步
对于添加任务这个行为,对应的Action Creator以下:ide
function addTask(name, category) { return { type: ADD_TASK, name, category }; }
Action对象仅仅是描述了行为的相关信息,至于如何经过特定的行为来更新state,就须要看看Reducer了。
关于Reducer,最简单的描述就是:
根据上面的描述,Reducer函数就能够表示为:
(previousState, action) => newState
Reducer函数的形式一般以下:
function reducer(state = [], action) { // 处理不一样action的代码 switch (action.type) { case SPECIAL_ACTION: // 根据SPECIAL_ACTION action更新state // 返回新的state default: return state } }
Actions描述了"what happened"的事实,Reducers则根据这些actions来更新state,而Store则是Actions和Reducers链接在一块儿的对象。
Store是Redux中数据的统一存储,维护着state的全部内容,因此Store的主要功能就是:
看到Store提供的方法,就能够把Action、Reducer和Store联系在一块儿了:
下面就来看看第二张图,跟第一张图的差异不大,只是增长了中间件(Middleware)来处理Action。
在Redux中,Middlerwares主要的做用就是处理Action,Redux中的Action必须是一个plain object。可是为了实现异步的Action或其余功能,这个Action可能就是一个函数,或者是一个promise对象。这是就须要中间件帮助来处理这种特殊的Action了。
也就是说,Redux中的Middleware会对特定类型action作必定的转换,因此最后传给reducer的action必定是标准的plain object。
针对Action的特征,Reudx Middleware能够采起不一样的操做:
Redux中经常使用的中间件:
通过前面的介绍,咱们已经看到了Redux中的一些核心概念。Redux跟React没有直接的关系,自己能够支持React、Angular、Ember等等框架。
经过react-redux这个库,能够方便的将react和redux结合起来:react负责页面展示,redux负责维护/更新数据状态。
到这里,第三张图就展现了react-redux这个库的工做原理,react和redux是怎么联系到一块儿的。
react-redux中提供了两个重要功能模块Provider和connect,这两个模块保证了react和redux之间的通讯,下面就分别看看这两个模块。
经过Provider的代码能够看到,Provide本质上是一个react组件。
export default class Provider extends Component { getChildContext() { return { store: this.store } } constructor(props, context) { super(props, context) this.store = props.store } render() { const { children } = this.props return Children.only(children) } }
Provider组件主要用到了react经过context属性,能够将属性(props)直接给子孙component,无须经过props层层传递,从而减小组件的依赖关系。
connect方法的主要做用就是让Component与Store进行关联, Store的数据变化能够及时通知Views从新渲染。
任何一个经过connect()函数处理过的组件均可以获得一个dispatch方法做为组件的props,以及获得全局state中的全部内容。
经过源码]能够看到,connect函数运行后,会返回一个wrapWithConnect函数,该函数能够接收一个react组件,而后返回一个通过处理的Connect组件。
return function wrapWithConnect(WrappedComponent) { class Connect extends Component { constructor(props, context) { // 从祖先Component处得到store this.store = props.store || context.store this.stateProps = computeStateProps(this.store, props) this.dispatchProps = computeDispatchProps(this.store, props) this.state = { storeState: null } // 对stateProps、dispatchProps、parentProps进行合并 this.updateState() } shouldComponentUpdate(nextProps, nextState) { // 进行判断,当数据发生改变时,Component从新渲染 if (propsChanged || mapStateProducedChange || dispatchPropsChanged) { this.updateState(nextProps) return true } } componentDidMount() { // 改变Component的state this.store.subscribe(() = { this.setState({ storeState: this.store.getState() }) }) } render() { // 生成包裹组件Connect return ( <WrappedComponent {...this.nextState} /> ) } } Connect.contextTypes = { store: storeShape } return Connect; }
文中不少Redux的概念都是进行了简单的介绍,更多详细的介绍能够参考我整理的内容,GitHub地址:WilberTian/StepByStep-Redux
每篇文章的结尾都会有一些简单的demo 代码,帮助理解文章中介绍的内容。
文中结合三张图片介绍了Redux中的一些核心概念,以及React和Redux之间经过react-redux这个库进行交互。
更多详细的内容,已经整理到了GitHub上了(WilberTian/StepByStep-Redux),经过这些介绍以及demo的运行结果,必定能对Redux有一个比较基本的认识。
全部的内容主要参考Usage with React,而后加上了本身的理解画了上面三张图,同时结合每一个概念写了一些demo帮助理解。