react中的setState的使用和深入理解


      前端框架從MVC過渡到MVVM。從DOM操作到數據驅動,一直在不斷的進步着,提升着,

      angular中用的是watcher對象,vue是觀察者模式,react就是state了,他們各有各的特點,沒有好壞之分,只有需求不同而選擇不同。

 

今天就着重詳細的隨手寫點我對react中state的理解:

      React通過管理狀態實現對組件的管理,通過this.state()方法更新state。當this.setState()被調用的時候,React會重新調用render方法來重新渲染UI。

     

在說setstate這個磨人的小妖精之前,不得不先說一下state這個小可愛了

      定義一個合適的State,是正確創建組件的第一步。因為有一些變量不需要響應式的使用,如果使用了state,就會給這個變量增加一些響應式掛載,要時            刻 記得做到完美  ^-^ 

  判斷是否可以做為一個state的條件:

        1、變量如果是通過props從父組件中獲取,就不是一個狀態

        2、如果這個變量可以通過其他的狀態state或者屬性props 通過數據處理得到,就不是一個狀態

  3、如果變量在render中沒有使用到,那就不是一個state

        4、變量在整個生命周期中都保持不變時,也不是一個狀態 

 其實使用的時候最多的使用到的就是state和props,他們兩個是有很大的區別的,最主要的區別就是:

  State是可變的,是組件內部維護的一組用於反映組件UI變化的狀態集合;

  而Props對於使用它的組件來說,是只讀的,要想修改Props,只能通過該組件的父組件修改。在組件狀態上移的場景中,父組件正是通過子組件的Props,          傳遞給子組件其所需要的狀態。

 

  在使用state的時候, 如果我們企圖直接修改state中的某一個值之后直接打印(使用)他,就會發現,他其實並沒有改變。

  就像下面的例子,企圖通過點擊事件之后就使用修改之后的state的值,但是會發state中的並沒有被立即修改,還是原先的值,我們都知道那是因為     setState就相當於是一個異步操作,不能立即被修改

     

       那么我們也都知道為了解決上面的問題會有很多方法例如:

  方法一:

  

       這個回調函數會在修改了state之后才會執行,這就就可以happy的使用修改之后的state的值了

       方法二:

     

       操作異步函數,用的最舒服的還是async / await 啦

  當然還有很多其他的解決辦法啦。。。。。。。。只是我會比較常用這兩種方法而已

      

      在使用setState的時候,有兩種格式;

     第一種setstate()格式  第一個參數是一個對象,第二個參數是一個回調函數,這個回調函數是在setstate執行完並頁面渲染了之后再執行

    

     但是這種修改的方式不穩妥,因為是直接修改,我還是比較喜歡使用第二種格式

    setstate的第二種格式,接收一個回調函數,而不是一個對象,這個回調函數有兩個參數,

    一個是接收前一個狀態值作為第一個參數,並將更新后的值作為第二個參數

    

     這種寫法在這個例子里有點大材小用了,但是在處理復雜數據和邏輯的時候會特別好用 !

     

 總的來說setstate這個磨人的小妖精就和Vue中的數據響應一樣,

 在Vue中,

Vue官網上偷的圖。。。。。。。。。。

組件、函數等渲染---->創建一個虛擬DOM樹------->當data、computed、props改變時會引起頁面的刷新--------watcher檢測變化,當變化以后不會 立  即渲染,會有一個隊列,只要觀察到數據變化,Vue 將開啟一個隊列,並緩沖在同一事件循環中發生的所有數據改變。如果同一個 watcher 被多次觸           發, 只會被推入到隊列中一次。這種在緩沖時去除重復數據對於避免不必要的計算和 DOM 操作上非常重要。然后,在下一個的事件循環“tick”中,Vue 刷          新隊列並執行實際 (已去重的) 工作。   

 

在react中

 可以看出在react中也是和Vue中的一樣,state的值在修改了之后並不會立即被修改,而是也有一個類似的隊列,setState通過一個隊列機制實現state的更新。當執行setState時,會把需要更新的state合並后放入狀態隊列,而不會立刻更新this.state,利用這個隊列機制可以高效的批量的更新state。

 

 真是一個神奇的方法,很喜歡這個可以高效批量更新state的機制,於是就去瞅了瞅setState的源碼,想看一下react是怎么構造出setState這個磨人的小妖精的

 

這個構造小妖精的過程也是磨人的。。。。。。理了好久才理清。。。。

 

 它的主要流程如下:

   1、當調用setState時,實際上會執行enqueueSetState方法,並對partialState以及_pendingStateQueue更新隊列進行合並,最終通過enqueueUpdate執行state更新

   2、 如果組件當前正處於update事務中,則先將Component存入dirtyComponent中。否則調用batchedUpdates處理。

而performUpdateIfNecessary方法獲取_pendingElement、_pendingStateQueue、_pendingForceUpdate,並調用reciveComponent和updateComponent方法進行組件更新。
   3、batchedUpdates發起一次transaction.perform()事務
   4、開始執行事務初始化,運行,結束三個階段
           初始化:事務初始化階段沒有注冊方法,故無方法要執行
            運行:執行setSate時傳入的callback方法,一般不會傳callback參數
             結束:更新isBatchingUpdates為false,並執行FLUSH_BATCHED_UPDATES這個wrapper中的close方法
     5、FLUSH_BATCHED_UPDATES在close階段,會循環遍歷所有的dirtyComponents,調用updateComponent刷新組件,並執行它的pendingCallbacks, 也就是setState中設置的callback。

 

 

 

 源碼部分有空補上。。。。。。

 

 

 

 

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM