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

  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/qianbin/p/10171834.html
Copyright © 2011-2022 走看看