zoukankan      html  css  js  c++  java
  • 笔记----深入浅出《React和Redux》第三章Flux框架

    书中的此章节“思想”类成分较多,需要理解的内容也相对较多,如果一一列举,本文就写的相对繁琐了,推荐有兴趣的同学可以去看一下书籍以及敲一下书中的代码,有助于理解作者大牛的思想,我就在此简略的记录一些相对重要的“点”了。

    一、Flux框架的诞生以及解决了MVC框架哪些问题

      1、Flux出现背景

          Facebook的工程部门发现在前端使用MVC框架进行逻辑划分时,在业务量和代码量庞大的情况下,model层和view层之间依赖过于复杂,不利于后期对于代码的维护

          

       理想中,各个模块分工:

       Model:负责逻辑以及数据

           View:负责渲染界面

           Controller:负责接收用户的输入,根据用户的输入调用对应的Model部分逻辑,把产生的数据结果交给View部分,让View渲染出必要的输出

       MVC框架的请求流程:用户请求------>Controller------>Model------>View,View和Model不能直接进行互相通信,都需要借助于Control

      

      

      在实际工作中,对于浏览器端 MVC 框架,存在用户的交互处理,界面渲染出来之后,Model 和 View 依然存在于浏览器中,这时候就会诱惑开发者为了简便,让现存的 Model和 View直接对话,当代码量和逻辑复杂时,使程序“脆弱而且不可预测”

      2、Flux框架

       

       (1)特点:更严格的数据流控制

           (2)各个模块:

                 Dispatcher(相当于“Controller”):用来接收Actions、执行回调函数;

         Store(相当于“Model”):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面;

         Action(相当于“用户请求”):视图层发出的消息;

                 View:显示用户界面;

      (3)与MVC框架的区别:

        (i)当系统需要扩充应用所能处理的“请求”时,在MVC中,通过在Controller增加函数,来实现扩充;

                   在Flux中,不需要Dispatcher增加新函数,而是通过增加新的Action类型,来实现扩充

      (4)Flux实践 (直接上代码)

        实现的效果:

           

            

                       当点击“+”按钮或者“-”按钮,对应行的数字会时时进行改变,并且总数也会时时改变,下图:

          

          

                  步骤一

            安装Flux:npm install --save flux             (如果感觉慢,可以安装国内淘宝镜像)

           

    (i)Dispatcher

                         

           作用:生成Dispatcher实例,用来之后将 Action 派发到 Store

           注意!注意! 注意!Dispatcher实例在全局只有一个

    (ii)Action(分2个文件,一个定义action类型,另一个定义action构造函数)

            ActionTypes.js

            

            说明:将常量放在单独一个文件方便管理

            Actions.js 

            

            作用:根据类型,生成不同的action对象,通过Dispatcher实例的dispatch函数派发出去

            注意:出于业界习惯,这个文件被命名为Actions.js,但是要注意里面定义的并不是action对象本身,而是能够产生并进行派发action对象的函数 

                            

    (iii)Store(创建了两个store,CounterStore是为Counter组件服务,SummaryStore是为总数服务)

            CounterStore.js

             

             

            说明:在CounterStore中可以看出,首先定义了Counter组件初始化的值,然后使用Object.assgin()函数,对EventEmitter.prototype对象进行了浅拷贝,并在此浅拷贝对象的基础上扩充了getCounterValues、emitChange、addChangeListener、removeChangeListener方法。其中这四个方法的后三个方法,分别调用了EventEmitter.prototype的on(),emit(),removeListener()方法,作用如下:

             on(EVENT_TYPE,callback):用来监听事件,第一个参数是字符串事件类型,第二个参数是事件处理函数;

             emit(EVENT_TYPE):用来触发事件,第一个参数是字符串事件类型;

             removeListener(EVENT_TYPE,callback):用来移除事件,如果要调用removeListener函数,就一定要保留对处理函数的引用,

                                                                                           第一个参数是字符串事件类型,第二个参数是事件处理函数。

    最后,通过把AppDispatcher.register()中的回调函数注册到Dispatcher上,来接受之前通过AppDispatcher.dispatch()派发的action对象,通过switch或if-else来实现对应类型的动作实现对应类型的操作。

            

            

            SummaryStore.js

             

             

            说明:总体代码和之前CounterStore差不多。需要说明的是在这两个store中,AppDispatcher.register()会返回一个标记,保存在各自store的dispatchToken字段中,用来之后实现多个store之间行为的依赖顺序,借助waitFor()。在这个代码中,我们希望SummaryStore的逻辑在CounterStore之后进行

            作用: Store是一个对象,既用于存储应用状态,也用来接受Dispatcher派发的动作,根据动作决定是否更新应用状态。

            注意:store 在Flux中可以存在多个,每一个 store 都会受到所有的 action 通知,然后自行觉得是否对这个 action 做出响应,更新 state;

                 store对外只暴露了读取接口,如果想实现写入的功能,只能去实现对应action。

         

    (iv)View(用React进行实现,3个视图组件,其中ControlPanel父组件包含Counter子组件,Summary子组件)

            

             ControlPanel组件

            

            Counter

                    

              

             Summary

             

            View 的代码就是常规React书写方式,就不一一叙述了

             注意:存在于Flux框架中的React组件需要实现以下几个功能

                  1)创建时要读取Store上的状态来初始化组件内部状态;(而不像之前通过props传参,实现组件内部初始化)

                2)当Store上状态发生变化时,组件要立刻同步更新内部状态保持一致;(通过Store改变状态后调用emit(),以及View通过on()来监听Store中状态的变化)

                3)View如果要改变Store状态,只能派发action。(Flux中,对Store进行修改,只能通过新建action)

    (v)上述代码个人理解及总结:

    过程一:按着组件的生命周期函数顺序,进行渲染。其中componentDidMount函数通过CounterStore.addChangeListen函数监听了CounterStore的变化之后,只要CounterStore发生变化,Counter组件的onChange函数就自动会被调用。不过首次挂载时,可以发现getCounterValue被重复调用了2次来读取相同值,分别是第一个是constructor中被调用,第二个是componentDidMount中的this.onChange中被调用

                  

                  

                      

       

    过程二:当进行点击“+”按钮时,this.props.caption立即读取了当前组件上的属性值First,以形参的形式传入increment()方法,并触发increment();

                  (以First为例子)         

                      

    过程三:此时Dispatcher的实例(AppDispatcher)调用dispatch()方法,将刚产生的action对象派发出去,此时action对象上携带着动作类型,以及刚刚传入的First字符串标记

                               

    过程四: 通过AppDispatche.register()来注册回调函数,之后这个回调函数就可以接受派发出来的action对象,并根据这个action对象的类型,执行对应的逻辑,即在这里的逻辑是根据action.counterCaption拿到First,然后通过counterValues[First]拿到当前保存在Store中的初始值,并进行加一操作,最后通过emit(),将事件触发

                            

                 

    过程五:在过程一首次挂载时,onChange函数作为形参数,最终传入on()中,监听事件的触发,也就是等待emit函数被调用,然后执行onChange函数内部操作,通过getCounterValues获得Store的新状态值,即First字段加一后的值,最后通过setState函数将这个值同步到组件内部状态count上,同时State的更新会触发生命周期的shouldComponentUpdate函数,判断此次渲染是否与上一次不同,如果不同则返回true,并将结果渲染到页面 

                

                 

                            

                 其他的“-”按钮以及计算总和的步骤流程也差不多,我就不继续进行描述了,可以按照上面过程进行推演。 

                结合自己理解,画了一个图,完毕。

                

    3、Flux框架的优点:

    (1)对比纯粹使用React框架,当多个组件或者组件之间多层嵌套的情况下,对一个全局变量进行操作,只通过props进行操作显的特别的麻烦,

           在使用Flux框架情况下,React组件在其中只充当了View并对Store进行了时时的监听,全局变量由Store进行保存,组件可以通过action对Store进行操作,并反馈到View。

           避免的props带来的繁琐,不过程序如果不复杂,使用Flux也可能把“简单问题复杂化”,使用时视情况而定。

    (2)对比前端MVC框架,他的“单向数据流”管理方式更加的严格。

    4、Flux框架不足: 

    (1) 多个Store之间的依赖

    (2) Store混杂逻辑和状态

    睡觉睡觉!!!!!!!未完待续~~~

    其他参考:http://www.ruanyifeng.com/blog/2016/01/flux.html

  • 相关阅读:
    springBoot从入门到源码分析
    MQ疑难杂症小记
    dubbo学习思路梳理
    Zookeeper
    分布式系统理论概述
    mysql,存储引擎,事务,锁,慢查询,执行计划分析,sql优化
    tomcat学习步骤,附带打破双亲委派模型企业应用实战
    使用UtraISO为U盘制作系统启动盘
    洛谷P3369 splay或treap
    gym 101982 B题 Coprime Integers
  • 原文地址:https://www.cnblogs.com/qianbin/p/10171834.html
Copyright © 2011-2022 走看看