筆記----深刻淺出《React和Redux》第二章

1、prop和statereact

一、易於維護組件的設計要素瀏覽器

(1)高內聚:把邏輯緊密的相關內容放在一個組件中服務器

(2)低耦合:不一樣組件之間的依賴關係儘可能弱化函數

 

二、React組件的數據
測試

     分兩種(都會引起組件的從新渲染):ui

    prop:組件對外接口;(通常用在組件之間傳參)this

            state:組件內部狀態;(通常用在組件內部初始化)spa

     

三、React的prop:組件的prop很像是HTML元素的屬性,可是HTML元素的屬性值都是字符串,而React組件的prop所支持的類型幾乎包含人一JS中所支持的類型設計

   注意:3d

              <SampleButton id=」 sample」  borderWidth={2}  onClick={onButtonClick}   style={{color: 」 red」}}  />

    style值中的{{}} , 外層表示JSX語法,內層表示對象

 

   (1)賦值 

      引入主入口組件App(另外一個組件是第一章的demo)

                  

 

                 

      向三個ControlPanel的子組件Counter進行賦值,使用了caption和initValue兩個prop

       

  (2)讀取prop值

                 

                 經過props 進行 讀取值

 

      結果顯示:

                     

 

   (3)propType進行prop接口規範 

                             

                  此時對prop值進行了約束,

                            對caption必須是string,而且isRequired表示caption爲必填值

                            對initValue必須爲number

 

                  若是不按約束標準進行,如

                             

                 則報錯 

                            

 

     注意:

                    即便在上面 propTypes 檢查出錯的狀況下,組件依舊能工做 。 也就是說 propTypes檢查只是一個輔助開發的功能,並不會改變組件的行爲。

       

 

四、React的state:幫助記錄組件自身的數據變化

              注意:組件的state必須是JS對象,不能是其餘數據類型

 

  (1)初始化值

            

    能夠換一種更優雅的寫法

            

           同樣能夠實現默認值爲0的效果

 

  (2)讀取和更新state

            

    

    若是不使用setState(),修改代碼以下

       

       此時點擊「+」,則會彈出警告

        

 

     注意:

      在不使用setState()狀況下,當連續點擊10次「+」,數值並無發生改變

                

          而後再次點擊「-」時,數值直接變成9

            

      能夠看出在咱們連續點擊「+」,其實state值已經開始進行累加,可是沒有渲染到頁面上,當咱們點擊「-」時,使用setState(),將減去1以後的結果9顯示在頁面上

      總結:直接使用state修改值,只修改了內部狀態,並無引發從新渲染

 

五、prop和state的對比

      (1)prop定義外部接口,state記錄內部狀態

  (2)prop的賦值在組件外部,state的賦值在組件內部

    (3)組件不該該改變prop的值,而state的值容許被修改

    (

      組件不該該改變prop的值的緣由:

             假設一個場景,父組件包含多個子組件,而後將一個JS對象做爲prop值傳給這幾個子組件,而某個子組件修改了這個對象的內部值,

                        那麼其餘子組件在讀取那個對象的值時都會受到影響,致使程序混亂

        

        書上沒有實踐案例,本身寫個小demo測試一下(將以前代碼都放demo1了,這次新建立demo2),以下:

          

          

          首先,將父組件引入主入口文件

 

                                        

           在Parent組件中,初始化content對象,並將它做爲prop值,分別傳入兩個子組件

           

          

          

          ChildOne組件對prop值進行直接修改,ChildTwo組件中對prop值進行顯示,觀察prop值是否變化

          

          結果:

          

          先點擊ChildOne,而後點進ChilTwo進行顯示,發現prop值在子組件Children發生改變,丟失了最初的值

           

                    

          

               )    

 2、組件的生命週期(v16.6.0)

    截取react官網生命週期圖

                                                         

       (1)裝載過程(Mount):組件第一次在DOM樹中渲染過程;

       (2)更新過程(Update):當組件被從新渲染過程;

       (3)卸載過程(Unmount):組件從DOM中刪除的過程;

   

一、裝載過程的對應函數:

(1)constructor:當建立組件類的實例時,會調用對應構造函數

       注意:無狀態的React組件,不須要定義構造函數

     

   React組件定義構造函數的目的:

                (i)初始化state

                (ii)綁定成員函數的this環境

注意:

      在ES6語法下,類的每一個成員函數在執行時的this並非和類實例自動綁定的,而在構造函數中,this就是當前組件的實例

  因此,爲了方便未來的調用,在構造函數中將這個實例的特定函數綁定this爲當前實例。

 如:

   this .onClickincrementButton = this .onClickincrementButton.bind(this);

      

(2)render:React組件中最重要的函數,一個React組件能夠不實現其餘全部函數,可是必定要實現render函數

    (i)某些特殊組件不是用來渲染界面,就讓render函數返回一個null或者false,等於告訴React,這個組件不須要渲染DOM元素

            (ii)render函數是一個純函數,根據this.state和this.props決定返回結果,不能在裏面進行this.setState改變狀態

       

(3)componentWillMount和componentDidMount:

    (i)componentWillMount:這個函數在渲染前被調用,幾乎不會被使用到,由於全部能夠在這個 component­WillMount 中作的事情,均可以提早到 constructor 中間去作

            (ii)componentDidMount:這個函數被調用時,組件已經被裝載到DOM樹上了

注意:

                

             執行順序,結果:

    

  

           能夠看出componentWillMount緊貼着本身組件的render函數以前被調用,componentDidMount在三個組件的render函數都被調用以後,

          三個組件的componentDidMount才連着被一塊兒調用。

         

 緣由:

       是由於 render 函數自己並不往 DOM 樹上渲染或者裝載內容,它只是返回一個 JSX表示的對象,而後由 React庫來根據返回對象決定如何渲染。而 React庫確定是要把全部組件返回的結果綜合起來,才能知道該如何產生對應的 DOM修改。 因此,只有 React庫調用三個 Counter組件的 render函數以後,纔有可能完成裝載,這時候纔會依次調用各個組件的 componentDidMount 函數做爲裝載過程的收尾 。

                

 

     (iii)componentWillMount能夠在服務器端或瀏覽器端被調用,componentDidMount只能在瀏覽器端被調用

             (iv)在 componentDidMount 被調用的時候,組件已經被裝載到 DOM 樹上了,能夠配合其餘的第三方UI庫(如:jQuery),進行添加新的功能

 

 

二、更新過程的對應函數:

(1)componentWillReceiveProps(nextProps)

              (i)經過 this.setState方法觸發的更新過程不會調用這個函數;

              (ii)只要是父組件的render函數被調用,在render函數裏面被渲染的子組件就會經歷更新過程,

                   無論父組件傳給子組件的props有沒有改變,都會觸發子組件的componentWillReceiveProps函數

 

  根據以下例子證實:

    父組件

    

        當觸發onClick事件時,引起一個匿名函數,經過forceUpdate進行從新繪製(每一個React組件均可以經過forceUpdate函數強行進行從新繪製)

 

    子組件

    

    

    運行結果

     

     顯示頁面初始化的數據,當進行點擊Click me to repaint!時

    

           

    此時能夠看出:

                     執行次序是當父組件的render被調用後,引起了子組件中componentWillReceiveProps的調用,最後子組件中的render也被調用了;

       再次渲染子組件時,它們的props並無變化,可是子組件中componentWillReceiveProps依然被調用了  (有須要在子組件對nextProps和this.props值進行比較)

 

    再驗證一下this.setState能不能觸發componentWillReceiveProps

                         

    此時能夠看出:                                      

       當前組件調用this.setState函數,不會引起componentWillReceiveProps函數             

    

(2)shouldComponentUpdate(nextProps,nexState):除了render以外最重要的函數,經過返回的布爾值決定何時組件不須要渲染,

         (i)若是咱們要定義 shouldComponentUpdate,那就根據這兩個參數,外加 this.props和 this.state來判斷是返回true,仍是false,來避免重複渲染

   (ii)經過this.setState函數引起更新過程,並非馬上更新組件的state值,在執行到函數shouldComponentUpdate的時候,this.state依然是this.setState函數執行以前的值 

 

    如:

     

 

     運行結果:

            

    能夠看出,三個Counter組件的render函數沒有被調用,由於這個刷新沒有改變caption值或count,減小了沒必要要的渲染

 

(3)componentWillUpdate和componentDidUpdate

    (i) componentDidUpdate函數,不只在瀏覽器端能夠執行,服務器端也能夠執行

    (ii)在配合其餘第三方UI庫時(如:jQuery),當React組件被更新時,原有內容會被從新繪製,這時候須要在componentDidUpdate函數再次調用jQuery代碼

 

三、卸載過程的對應函數:

  (1)componentWillUnmount:當React組件要從DOM樹上刪除以前,此函數會被調用,適合作一些清除工做(如:防止內存泄漏)

 

3、組件向外傳遞數據         

                         

      

        

        經過onUpdate這個prop值爲onCounterUpdate函數,做爲「橋樑」,經過函數的參數進行「溝通」

 

 

其餘參考:https://react.docschina.org

相關文章
相關標籤/搜索