笔记----深入浅出《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对象)

 

    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流程

 

                                    

 

 

  

部分参考

https://redux.js.org/

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html

https://css-tricks.com/learning-react-redux/

 

posted @ 2019-01-02 16:55  clicli  阅读(436)  评论(0编辑  收藏  举报