理解React組件的生命週期

React提供了不少鉤子函數使咱們能夠在合適的時間、合適的節點更新組件的狀態,這些鉤子是生命週期函數,想要使用React,咱們必須掌握在鉤子中能夠作什麼,不能夠作什麼。html

??首先你們想一下在哪裏發送請求比較合適 componentWillMountcomponentDidMountcomponentWillReceivePropscomponentDidUpdate?

reactlifecycle.png

組件3個階段

組件的生命主要包括3個階段: 掛載、更新、卸載,React 16開始還添加了錯誤處理。react

掛載

組件被實例化並掛載在到dom樹這一過程稱爲掛載git

mounting.png

  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()

更新

當組件的屬性或者狀態改變時會從新渲染github

updating.png

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

當執行this.forceUpdate時,shouldComponentUpdate將不會被觸發編程

forceUpdate.png

卸載

當一個組件被移出Dom樹時,組件就會被卸載小程序

  • componentWillUnmount()

Error Handling

error-handleing.png

  • componentDidCatch()

constructor

當組件被實例化時,構造函數就被會最早執行。須要注意的是constructor的第一行必須是super(props)語句。segmentfault

DO瀏覽器

  1. 設置組件的初始狀態
  2. bind function

簡單解釋下bind function,當類的方法做爲事件處理函數時,有可能會丟失this指向,有兩種常見的解決方案:dom

// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this); // 上面提到的bind function
使用箭頭函數聲明處理函數,我的比較推薦這種方案,代碼簡潔乾淨
handleClick = () => {}

DON’T異步

  1. 向後臺發送請求進而更新組件狀態
  2. 使用this.setState初始化

下圖是強行在constructor中調用this.setState所發出的警告,在constructor中調用this.setState是沒有任何做用的

setStateError.png

componentWillMount

它也只會在掛載過程當中被調用一次,它的做用和constructor沒有太大差別。有不少人在componentWillMount中請求後臺數據,認爲這樣能夠更早的獲得數據,componentWillMout是在render函數執行前執行的,雖然請求是在第一次render以前發送的,可是返回並不能保證在render以前完成。React中不推薦在componentWillMount中發送異步請求?。

還有一點須要瞭解: 在componentWillMount中執行this.setState是不會觸發二次渲染的。仔細思考一下,componentWillMount好像沒啥卵用了。正所謂存在即合理,在服務端渲染的場景中componentDidMount是不會被執行的,所以能夠在componnetWillMount中發生AJAX請求。

DO

  1. 使用this.setState更新組件狀態
  2. 發送AJAX請求(服務端渲染場景中)

DON’T

  1. 發送AJAX請求(瀏覽器渲染場景中)

componentDidMount

此函數只會被調用一次既組件掛載完成時,在render函數調用以後。組件掛載完成表示它的子組件也所有被掛載完成。父組件render ->子組件render->子子組件render ... ...子子組件DidMount -> 子組件DidMount -> 父組件DidMount。React就是個遞歸的世界。componentDidMount函數中能夠發生異步請求。

DO

  1. 發送AJAX請求

DON’T

  1. this.setState更新狀態,由於會觸發二次渲染

componentWillReceiveProps

當父組件re-render時該鉤子函數就會執行,即便所傳入的屬性沒有改變。這個鉤子最大的用途:組件的部分狀態是依賴於屬性時作狀態同步使用,在其中使用this.setState是不會觸發額外的渲染的,this.setState的狀態更新和props觸發的render合併一次進行。要合理使用componentWillReceiveProps需記住作好條件判斷:

componentWillReceiveProps(nextProps) {
  if(nextProps.myProp !== this.props.myProps) {
    // nextProps.myProp has a different value than our current prop
  }
}

請不要嘗試在componentWillReceiveProps中發送異步請求(React Fiber後該鉤子函數可能會被觸發屢次)?

DO

  1. 根據Props的更新同步組件狀態

DON’T

  1. 發生異步請求

shouldComponentUpdate

shouldComponentUpdate主要是用來優化React應用性能的,水平沒達到必定高度就不要去動它了。組件的狀態或者屬性改變時都會觸發該函數,但只有在返回true時,組件纔會被從新渲染。

DO or DON’T
什麼也不要作就對了?

componentWillUpdate

當咱們沒有覆寫componentShouldUpdate時,componentWillUpdate會在其以後當即執行。當shouldComponent被覆寫過期,componentWillUpdate主要用來取代componentWillReceiveProps,用來同步Props至組件的部分狀態。

DO

  1. 同步Props到組件狀態

DON’T

  1. 發生異步請求

componentDidUpdate

它和componentDidMount的功能相似,componentDidMount發生於組件的首次render以後,而componentDidUpdate則是發生於組件狀態及屬性變化所致使的re-render以後。主要是用來請求後臺數據。和componentWillReceiveProps相似,作相應處理時,須要作屬性是否變動的判斷,以下面代碼所示。有趣的一點: componentWillReceiveProps接收的參數是nextProps, componentDidUpdate接收的是preProps。

componentDidUpdate(prevProps) {
  if(prevProps.myProps !== this.props.myProp) {
    // this.props.myProp has a different value
    // ...
  }
}

DO

  1. 異步請求

DON’T

  1. this.setState更新狀態,會觸發二次渲染

componentWillUnmount

當組件被卸載時被調用,在這裏主要作一些清理操做,清理定時器、關閉socket、清除監聽器等等

componentDidCatch

React的錯誤機制:子組件中產生的錯誤若並未被捕獲或處理會拋給父組件,若上層也一直沒有處理,錯誤將會被拋至最頂層致使瀏覽器白屏。
React16開始添加了一個新的特性錯誤處理。componentDidCatch十分特別,它只能夠處理子組件中產生的、未處理的錯誤,可以捕獲的錯誤類型有子組件render函數中產生的錯誤及生命週期函數中產生的非異步錯誤。用法:

//父組件或祖宗組件中實現
componentDidCatch(errorString, errorInfo) {
  this.setState({
    error: errorString
  });
  ErrorLoggingTool.log(errorInfo);
}
render() {
  if(this.state.error) return <ShowErrorMessage error={this.state.error} />
  return (
    // render normal component output
  );
}

在哪請求數據

??首先你們想一下在哪裏發送請求比較合適componentWillMountcomponentDidMountcomponentWillReceivePropscomponentDidUpdate?

componentDidMountcomponentDidUpdate中。?

本文是閱讀了Understanding React — Component life-cycle和官方文檔後作的總結,也能夠說是我抄來得?,歡迎你們批評指正。code
React系列課程之 入門

Understanding React — Component life-cycle
React.Component
component-lifecycle-methods

【開發環境推薦】 Cloud Studio 是基於瀏覽器的集成式開發環境,支持絕大部分編程語言,包括 HTML五、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,無需下載安裝程序,一鍵切換開發環境。 Cloud Studio提供了完整的 Linux 環境,而且支持自定義域名指向,動態計算資源調整,能夠完成各類應用的開發編譯與部署。
相關文章
相關標籤/搜索