深刻淺出react和redux筆記

一直在用vue寫項目,react的項目接觸的少,花費四個多月學習了react相關知識。javascript

這本書質量很高,值得學習。

本身也動手擼了一個react全家桶的項目,是結合antd UI組件開發的,歡迎點贊👍👍👍前端

GitHub地址 github.com/zhaotbj/rea…vue

第二章 設計高質量的react組件

props和pros驗證

style的值有兩層花括號,外層花括號表明是jsx的語法,內層的花括號表明這是一個對象常量。java

<Counter onUpdate={this.onCounterUpdate} caption="First" />
        <Counter onUpdate={this.onCounterUpdate} caption="Second" initValue={this.initValues[1]} />
        <Counter onUpdate={this.onCounterUpdate} caption="Third" initValue={this.initValues[2]} />
複製代碼
// 在子組件中進行props 驗證
Counter.propTypes = {
  caption: PropTypes.string.isRequired,
  initValue: PropTypes.number,
  onUpdate: PropTypes.func
};
複製代碼

也能夠給props設置默認值react

複製代碼

prop 和state的對比

  • prop 用於定義外部的接口,state用於記錄內部的狀態
  • prop 的賦值在外部世界使用組件時,state的賦值在組件內部,
  • 組件不該該改變prop的值,而state存在的目的就是讓組件來改變的
  • 組件的state修改 使用 setstate 注意:組件不能去修改傳入的props的值, 一個子組件不能修改props的值。

組件的聲明週期

分爲三個大的過程git

  • 裝載過程
  • 更新過程
  • 卸載過程

裝載過程 當組件第一次被渲染的時候,依次調用的函數是

  • constructor
  • componentWillmount
  • render
  • componentDidMount

- constructor

  • 初始化state
  • 綁定成員函數的this環境

在ES6語法下,類的每一個成員函數在執行時的this並非和類實例自動綁定的。而在構造函數中,this就是當前組件實例,因此爲了方便未來的調用,每每在構造函數中將這個實例的特定函數綁定this爲當前實例。github

this.func=this.func.bind(this)
複製代碼

render 函數不作實際的渲染動做,它只是返回一個JSX描述的結構,最終由react來操做渲染過程。 若是這個組件不須要渲染的話就用render函數返回一個null 或者falseredux

componentWillmount會在render函數以前被調用,componentDidMount會在render函數以後被調用,這兩個函數就像是render函數的前哨和後哨,一前一後,把render函數夾住,正好分別作render先後的必要工做。數組

componentWillMount 將要裝載 這個時候沒有人會渲染出來的結果性能優化

componentDidMount 調用的時候組件已經被裝載到DOM樹上了。 render函數被調用完以後,componentDidMount函數並非會被馬上調用,componentDidMount被調用的時候,render函數返回的東西已經引起了渲染,組件已經被‘裝載’到了DOM樹上。

一個例子 渲染三個組件,當全部三個組件的render函數都被調用以後,三個組件的componentDidMount才連在一塊兒被調用。 之因此會出現這種狀況,是由於render函數自己並非一往DOM樹上渲染或者裝載內容,它只是返回一個JSX表示的對象,而後有react庫來根據返回對象決定如何渲染。而react庫確定是吧全部組件返回的結果綜合起來,才能知道該如何產生對應的DOM修改。 因此,只有react庫調用三個組件的render函數以後,纔有可能完成裝載。

在componentDidMount調用的時候,組件已經被裝載到DOM樹上了,能夠獲取渲染出來的任何dom。

更新過程

  • shouldCompontentUpdate

  • componentWillUpdate

  • render

  • componentDidUpdate

  • shouldCompontentUpdate 而shouldCompontentUpdate 決定了一個組件何時不須要渲染, 提升react組件性能。 render 和shouldCompontentUpdate函數,render函數返回結果將用於構建dom對象,shouldCompontentUpdate函數返回的是一個布爾值,告訴react庫這個組件在此次更新過程當中是否要繼續。

在更新的過程當中,react庫先調用而shouldCompontentUpdate函數,若是這個函數返回true,那就會繼續更新過程,接下來調用reader函數,反之,若是獲得的是一個false,那就馬上中止更新過程,也就不會引起後續的渲染了。

shouldComponentUpdate(nextProps, nextState) {
    return (nextProps.caption !== this.props.caption) ||
           (nextState.count !== this.state.count);
  }
複製代碼

shouldCompontentUpdate 接收兩個參數nextProps, nextState值, 在經過this.setState函數引起更新過程,並非馬上更新組件的state值,在執行到函數 shouldComponentUpdate的時候,this.state依然是this.setState函數執行以前的值,因此咱們要作的實際上就是在nextProps、nextState、this.props和this.state中互相對比。

  • componentWillUpdate和componentDidUpdate

若是shouldCompontentUpdate函數返回的是true,react接下來就會依次調用對應組件的componentWillUpdate、render和componentDidUpdate函數。

卸載過程

componentWillUnmount, 當react組件要從dom樹上刪除掉以前被調用。 這個函數適合作一些清理性工做。

redux

redux 三個基本原則

  • 惟一數據源
  • 保持狀態只讀
  • 數據改變只能經過純函數完成
  1. 惟一數據源 指應用的狀態數據應該只存儲在惟一的一個store上

  2. 保持狀態只讀 不能直接修改狀態,要修改store的狀態,必需要經過派發一個action對象完成。 數據改變只能經過純函數reducer完成

  3. reducer有兩個參數是state,action 第一個是當前的狀態,第二個是action是接收到的action對象。 reducer函數要作的事情,就是根據state和action的值產生一個新的對象返回,注意reducer必須是純函數,也就是說函數的返回結果必須徹底由參數state和action決定,並且不產生任何反作用,也不會修改參數state和action對象。

react-redux

export default connect(mapStateToProps, mapDispatchToProps)(EditTable);
複製代碼

react-redux 的兩個主要的功能 connect 鏈接容器組件和傻瓜組件 provider 提供包含store的context connect是react-redux提供的方法,這個方法接受兩個參數mapStateToProps和 mapDispatch-ToProps,執行結果依然是一個函數,說以才能夠在後面又加一個圓括號,把connect函數執行的結果馬上執行,這一次參數是counter這個傻瓜組件。

connect

這個connect函數具體作了什麼工做呢?

  • 把store上的狀態轉化爲內層傻瓜組件的prop
  • 把內層傻瓜組件中的用戶動做轉化爲派發給store的動做。 這兩個工做一個是內層傻瓜對象的輸入,一個是內層傻瓜對象的輸出。

這兩個的工做,是把store上的狀態轉化爲內層組件的props,其實就是一個映射關係,去掉框架,最後就是一個mapStateToProps函數該作的事情。

provider

第五章 react組件的性能優化

單個組件的性能優化 react利用虛擬DOM來提升渲染性能,雖然每一次頁面更新都是對組件的從新渲染,可是並非將以前渲染的內容所有拋棄重來,藉助虛擬DOM,react可以計算出對dom樹的最少修改

可是計算虛擬DOM也是一個很複雜的過程。

shouldComponentUpdate是默認方式,默認返回true,也就是說默認每次更新的時候都要調用全部的生命週期函數,包括render函數,根據render函數的返回結果計算虛擬dom。

就是在編寫邏輯的時候返回false。 本身每一個組件都寫很麻煩, 二react-redux庫,

export default connect(mapStateToProps, mapDispatchToProps)(EditTable);
複製代碼

connect的過程實際上產生了一個無名的react組件類,這個類定製了shouldComponentUpdate函數的實現,實現邏輯是比對此次傳遞給內層組件的props和上一次的props,她的渲染結果徹底由傳入的props決定,若是props沒有變化,那就能夠認爲渲染結果確定同樣。

問題是react-redux的渲染比較是淺層比較,簡單的說若是prop的類型是複雜對象,傳入兩次相同的props也會重新渲染。

爲何是淺層比較 不知道prop是有多少層

多個子組件的狀況

使用key,給每個子組件增長一個key屬性,且這個key是惟一的,這個key不該該是數組的下標。


歡迎加入大前端學習交流羣 😎🔥🔥🔥

相關文章
相關標籤/搜索