筆記----深刻淺出《React和Redux》第三章Flux框架

書中的此章節「思想」類成分較多,須要理解的內容也相對較多,若是一一列舉,本文就寫的相對繁瑣了,推薦有興趣的同窗能夠去看一下書籍以及敲一下書中的代碼,有助於理解做者大牛的思想,我就在此簡略的記錄一些相對重要的「點」了。html

 

1、Flux框架的誕生以及解決了MVC框架哪些問題前端

  一、Flux出現背景npm

      Facebook的工程部門發如今前端使用MVC框架進行邏輯劃分時,在業務量和代碼量龐大的狀況下,model層和view層之間依賴過於複雜,不利於後期對於代碼的維護瀏覽器

      

   理想中,各個模塊分工:框架

   Model:負責邏輯以及數據函數

       View:負責渲染界面this

       Controller:負責接收用戶的輸入,根據用戶的輸入調用對應的Model部分邏輯,把產生的數據結果交給View部分,讓View渲染出必要的輸出spa

 

   MVC框架的請求流程:用戶請求------>Controller------>Model------>View,View和Model不能直接進行互相通訊,都須要藉助於Controlprototype

  

 

  

  在實際工做中,對於瀏覽器端 MVC 框架,存在用戶的交互處理,界面渲染出來以後,Model 和 View 依然存在於瀏覽器中,這時候就會誘惑開發者爲了簡便,讓現存的 Model和 View直接對話,當代碼量和邏輯複雜時,使程序「脆弱並且不可預測」3d

 

  二、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,並將結果渲染到頁面 

            

             

                        

 

             其餘的「-」按鈕以及計算總和的步驟流程也差很少,我就不繼續進行描述了,能夠按照上面過程進行推演。 

 

            結合本身理解,畫了一個圖,完畢。

            

三、Flux框架的優勢:

(1)對比純粹使用React框架,當多個組件或者組件之間多層嵌套的狀況下,對一個全局變量進行操做,只經過props進行操做顯的特別的麻煩,

       在使用Flux框架狀況下,React組件在其中只充當了View並對Store進行了時時的監聽,全局變量由Store進行保存,組件能夠經過action對Store進行操做,並反饋到View。

       避免的props帶來的繁瑣,不過程序若是不復雜,使用Flux也可能把「簡單問題複雜化」,使用時視狀況而定。

 

(2)對比前端MVC框架,他的「單向數據流」管理方式更加的嚴格。

 

 

四、Flux框架不足: 

(1) 多個Store之間的依賴

(2) Store混雜邏輯和狀態

 

 

 

 

 

 

睡覺睡覺!!!!!!!未完待續~~~

 

 

其餘參考:http://www.ruanyifeng.com/blog/2016/01/flux.html

相關文章
相關標籤/搜索