笔记----深入浅出《React和Redux》第三章Redux框架(不使用react-redux库)
二、Redux与Flux
Redux的三个基本原则
A、唯一数据源(全局只有一个Store)
B、保持状态只读(不能直接修改Store状态)
C、数据改变只能通过纯函数完成
1、Redux与Flux不同点
(1)Store保持唯一
(2) Store中的逻辑和保存的状态值分离(逻辑在reducer中处理)
2、Redux实践(实现与Flux相同功能的效果)
首先需要安装“redux” npm install --save redux
(1)Action(分两个文件,一个ActionType.js,另一个Actions.js)
ActionTypes.js(将常量单独拿出)
Actions.js
Redux中每个action构造函数都返回一个action对象(Flux中,是将action通过Dispatcher的实例调用dispatch函数派发出去)
注意:Redux中,没有Dispatcher
(2)Store
这里引入Redux库所提供的createStore函数。最后返回一个保存了应用所有 state 的对象(即store对象)
注意:(i)Redux的Store状态设计的主要原则就是“避免冗余的数据”。因为Counter状态数值相加就是Summary组件的状态值,所以不需要在为Summary单独在Store进行数据存储;
(ii)createStore的第二个参数可选,通常是服务器给出的,如果提供了这个参数,会覆盖reducer函数的初始化state
(3)Reducer
说明:reducer函数中有两个参数:
第一个参数为state,这个state指初始化状态值。如果createStore中,写了第二个参数,即指定初始化状态值,那么这个state默认就是createStore中第二个参数的值,如果createStore中没有指定第二个state初始化参数,则需要在reducer函数的参数中,为state的设定默认值 (通常为对象形式),否则在第一次创建存储时,会报错,如下
第二个参数为action, reducer在接受这个派发过来的action之后,产生一个新的状态值
其中:
return { ...state,[counterCaption]:state[counterCaption]+1 }
等同于
const newState = Object.assgin( { } , state ) ;
newState[counterCaption] ++ ;
return newState;
注意:(i)Reducer是一个纯函数,不能直接对输入值state进行修改。我们采用的是拷贝出一个新的state,然后进行相应操作
(ii)在实际中调用了reducer两次,一次是在创建存储时(返回初始化state,此时没action),然后在调度之后再次调用(返回与action对应的新state)。
(4)View (分3个组件,ControlPanel,Counter,Summary)
ControlPanel.js
Counter.js
说明:当点击“+”时,会将对应的action对象派发出去
注意:在Flux中,action构造函数既负责创造对象,又负责派发(通过Dispatcher实例的dispatch方法)
在Redux中,action构造函数只负责创建对象(派发通过store.dispatch)
Summary.js
(5)最后理一下整个过程(还是以点击“+”按钮为例)
过程一:先按着组件生命周期函数顺序进行初始化加载。并在componentDidMount()中,通过store.subscribe中放入onChange监听器,监听store状态变化
过程二:当点击“+”按钮时
(以第一个Counter为例)
拿取Counter上caption的属性值,并传入increment中,生成一个新的action,然后通过store.dispatch派发
过程三:在过程二中派发action,此时被reducer函数接收,并根据action对象中的动作类型作出相应的“加一”操作,最后返回一个新的state,当然了,这个过程是在createStore函数内部发生的,毕竟我们只给createStore函数传入的只是reducer这个函数名,最后createStore返回一个Store对象
过程四:store发生了变化了,被store.subscribe监听到,通过store.getState拿到新的store,并将其渲染到页面上
3、拓展:
createStore是redux中重中之重的知识点,我在网上找了一下createStore源码,最后还是选择了阮一峰老师的简单实现版,简单实现版中getState,dispatch,subscribe和源码思路差不多,为了直观,我把他整合在之前的demo中,方便理解
(此时将原先从“redux”库中引入的createStore注释了)
最后也可以实现同样效果
结合自己的demo,我也标记了一些自己的理解注释
4、总结Redux流程
部分参考
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
https://css-tricks.com/learning-react-redux/