React生命週期 (V16.3以前與以後)

V16.3以前

圖解

圖解

生命週期總覽

react的生命週期大概分爲前端

  • 組件裝載(Mount)組件第一次渲染到Dom樹
  • 組件更新(update)組件state,props變化引起的從新渲染
  • 組件卸載(Unmount)組件從Dom樹刪除

組件裝載過程

  • constructor: 在此初始化state,綁定成員函數this環境,props本地化
  • componentWillMount: 預裝載函數,不能進行修改state的操做,即便作了,也不會進行新數據狀態的渲染。在該函數中作的操做,均可以提早到構造函數中。
  • render: 渲染函數,惟一的必定不能省略的函數,必須有返回值,返回null或false表示不渲染任何DOM元素。它是一個僅僅用於渲染的純函數,返回值徹底取決於this.state和this.props,不能在函數中任何修改props、state、拉取數據等具備反作用的操做。render函數返回的是JSX的對象,該函數並不由於這渲染到DOM樹,什麼時候進行真正的渲染是有React庫決定的。(setState是一個異步函數)
  • componentDidMount: 掛載成功函數。該函數不會再render函數調用完成以後當即調用,由於render函數僅僅是返回了JSX的對象,並無當即掛載到DOM樹上,而componentDidMount是在組件被渲染到DOM樹以後被調用的。另外,componentDidMount函數在進行服務器端渲染時不會被調用。

組件更新過程

當組件掛載到DOM樹上以後,props/state被修改會致使組件進行更新操做。更新過程會以此調用以下的生命週期函數:java

  • componentWillReceiveProps(nextProps): 該函數在組件進行更新以及父組件render函數(無論數據是否發生了改變)被調用後執行,this.props取得當前的props,nextProps傳入的是要更新的props。一般是比較this.props和nextProps來從新setState。
  • shouldComponentUpdate(nextProps, nextState): 返回bool值,true表示要更新,false表示不更新,使用得當將大大提升React組件的性能,避免不須要的渲染。
  • componentWillUpdate: 預更新函數。
  • render: 渲染函數。
  • componentDidUpdate: 更新完成函數。 相比裝載過程的生命週期函數,更新過程的生命週期函數使用的相對來講要少一些。經常使用的是componentWillReceiveProps、componentShouldUpdate,前者常常用於根據先後兩個數據去設置組件的狀態,然後者則是經常使用於優化,避免沒必要要的渲染。

組件卸載過程

卸載過程只涉及一個函數componentWillUnmount,當React組件要從DOM樹上刪除前,會調用一次這個函數。這個函數常常用於去除componentDidMount函數帶來的反作用,例如清楚計時器、刪除componentDidMount中創造的非React元素。react

注意事項

setState

要修改state,只能使用this.setState(),不能使用this.state.value='myData' 相似方式設置state,一是不會驅動從新渲染,二是極可能被後面的操做替換,形成沒法預知的錯誤。此外,React利用狀態隊列來實現setState的異步更新,避免頻繁地重複更新state。當同時作了不少setState操做的時候,react會智能的合併成一個setState,當須要肯定的setState完成後的操做,可使用web

setState({}, () => {
    // 在這裏進行state改變後的操做
    })
複製代碼

setState的調用是有風險的,在某些生命週期函數中調用可能會無用甚至早恆循環調用致使崩潰。state的初始化通常在構造函數中實現;setState能夠在裝載過程的componentWillMount、componentDidMount中調用;setState能夠在更新過程當中的componentWillReceiveProps、componentDidUpdate中調用服務器

render

render是一個異步函數,render執行後並不會直接生成Dom,而是生成虛擬Dom節點(模擬HTML Dom節點的一個javaScript數據結構),什麼時候生成真實的DOM樹取決於react框架自己的計算。 參考 騰訊前端數據結構

V16.3以後

圖解

圖解

新的生命週期

getDerivedStateFromProps

  • 觸發時間(v16.4修正):組件每次被rerender的時候,包括在組件構建以後(虛擬dom以後,實際dom掛載以前),每次獲取新的props或state以後。在v16.3版本時,組件state的更新不會觸發該生命週期。
  • 每次接收新的props以後都會返回一個對象做爲新的state,返回null則說明不須要更新state.
  • 配合componentDidUpdate,能夠覆蓋componentWillReceiveProps的全部用法
  • getDerivedStateFromProps是一個靜態函數,因此函數體內不能訪問this,輸出徹底由輸入決定。
static getDerivedStateFromProps(nextProps, prevState) {
  //根據nextProps和prevState計算出預期的狀態改變,返回結果會被送給setState
}
複製代碼

getSnapshotBeforeUpdate

  • 觸發時間: update發生的時候,在render以後,在組件dom渲染以前。
  • 返回一個值,做爲componentDidUpdate的第三個參數。
  • 配合componentDidUpdate, 能夠覆蓋componentWillUpdate的全部用法。

刪除生命週期

  1. componentWillReceiveProps
  2. componentWillMount
  3. componentWillUpdate

差別

全部被刪除的生命週期函數,目前還湊合着用,可是隻要用了,開發模式下會有紅色警告,在下一個大版本(也就是React v17)更新時會完全廢棄。框架

生命週期功能替換一覽

static getDerivedStateFromProps(nextProps, prevState) {
    4. Updating state based on props
    7. Fetching external data when props change
  }
  constructor() {
	1. Initializing state
  }
 
  componentDidMount() {
	2. Fetching external data
	3. Adding event listeners (or subscriptions)
  }
  
  shouldComponentUpdate() {
  }
  render() {
  }
  getSnapshotBeforeUpdate(prevProps, prevState) {
	8. Reading DOM properties before an update
  }
  componentDidUpdate(prevProps, prevState, snapshot) {
	5. Invoking external callbacks
	6. Side effects on props change
  }
  
  componentWillUnmount() {
  }
  
  // before
  
  componentWillMount() {
  	// 1. Initializing state
  	// 2. Fetching external data
  	// 3. Adding event listeners (or subscriptions)
  }
  componentWillReceiveProps() {
  	// 4. Updating state based on props
  	// 6. Side effects on props change
  	// 7. Fetching external data when props change
  }
  componentWillUpdate(nextProps, nextState) {
  	// 5. Invoking external callbacks
  	// 8. Reading DOM properties before an update
  }
複製代碼

參考 程墨dom

相關文章
相關標籤/搜索