React組件生命週期

  React是很火的前端框架,其最大的特色即是組件化。爲了迎娶白富美,當上CEO,走上人生巔峯,對這麼火的東東也有了必定的瞭解,可是對其生命週期只知其一;不知其二,因而去官方網站瞅了幾眼,結合本地實例,和你們共同窗習下React組件的生命週期。若是英文比較好的同窗能夠直接到https://facebook.github.io/re... 查看。javascript

建立一個React組件

官網說了,React中有一個React.Component類,這是一個抽象類,咱們不多會直接用到它,一般咱們寫一個子類去繼承它,而且在咱們的類中至少定義一個render()方法。html

class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

上面這個是ES6的寫法,固然若是沒有用ES6,那麼能夠向下面這樣去寫:前端

var Greeting = React.createClass({
  render: function() {
    return <h1>Hello, {this.props.name}</h1>;
  }
});

組件生命週期

每一個組件都有幾個生命週期函數,以will爲前綴的函數是在發生某些事以前調用,以did爲前綴的是在發生某些事以後調用java

Mounting

以下這些方法在組件實例被建立和被插入到dom中時被調用。react

  • constructor()
      constructor在組件被mounted以前調用,咱們的組件繼承自React.Component,constructor函數中咱們在其餘操做前應該先調用super(props),不然this.props將會是undefined。

  constructor初始化state的好地方。若是咱們不須要初始化state,也不須要bind任何方法,那麼在咱們的組件中不須要實現constructor函數。
  注意下面這種狀況,很容易產生bug,咱們一般的作法是提高state到父組件,而不是使勁的同步state和props。git

constructor(props) {
  super(props);
  this.state = {
    color: props.initialColor
  };
}
  • componentWillMount()
      此方法在mounting以前被當即調用,它在render()以前調用,所以在此方法中setState不會觸發從新渲染。此方法是服務器渲染中調用的惟一的生命週期鉤子,一般咱們建議使用constructor()。
  • render()
      render()方法是react組件必須的,它檢查this.props和this.state而且返回一個React元素,咱們也能夠返回null或false,表明咱們不想有任何的渲染。

  render()方法應該是一個純方法,即它不會修改組件的state,在每一次調用時返回一樣的結果。它不直接和瀏覽器交互,若是咱們想要交互,應該在componentDidMount()或者其餘的生命週期函數裏面。github

  • componentDidMount()
      此方法在組件被mounted以後當即被調用,初始化dom節點應該在此方法中,若是須要從遠端健在數據,這裏是實例化網絡請求的好地方,此方法中setState會觸發組件從新渲染。

Updating

props和state的改變產生更新。在從新渲染組建時,以下的方法被調用chrome

  • componentWillReceiveProps()
      一個已經mounted的組件接收一個新的props以前componentWillReceiveProps()被調用,若是咱們須要更新state來響應prop的更改,咱們能夠在此方法中比較this.props和nextProps並使用this.setState來更改state。

  注意,即便props沒有改變,React也能夠調用這個方法,所以若是你只想處理改變,請確保比較當前值和下一個值。當父組件致使你的組件從新渲染時,可能會發生這種狀況。
  React在組件mounting期間不會調用此方法,只有在一些組件的props可能被更新的時候纔會調用。調用this.setState一般不會觸發componentWillReceiveProps。瀏覽器

  • shouldComponentUpdate()
      使用此方法讓React知道組件的輸出是否不受當前state或props更改的影響。默認行爲是在每次state更改時從新渲染組件,在大多數狀況下,咱們應該默認改行爲。

  當接收到新的props或state時,shouldComponentUpdate()在渲染以前被調用。默認返回true,對於初始渲染或使用forceUpdate()時,不調用此方法。返回false不會阻止子組件的state更改時,該子組件從新渲染。
  若是shouldComponentUpdate()返回false,那麼componentWillUpdate(),render()和componentDidUpdate()將不會被調用。在未來,React可能將shouldComponentUpdate()做爲提示而不是strict指令,返回仍然可能致使組件從新渲染。前端框架

  • componentWillUpdate()
      當接收新的props或state時,componentWillUpdate()在組件渲染以前被當即調用。使用此函數做爲在更新發生以前執行準備的機會。初始渲染不會調用此方法。

注意:這裏不能調用this.setState()(若是調用會怎麼樣?好奇心很重呀,試了一下,會產生死循環,一直更新。。。)。若是咱們須要更新state以響應props的更改,咱們應該使用componentWillReceiveProps()

  • render()
      render()方法是react組件必須的,它檢查this.props和this.state而且返回一個React元素,咱們也能夠返回null或false,表明咱們不想有任何的渲染。

  render()方法應該是一個純方法,即它不會修改組件的state,在每一次調用時返回一樣的結果。它不直接和瀏覽器交互,若是咱們想要交互,應該在componentDidMount()或者其餘的生命週期函數裏面。

  • componentDidUpdate()
      此函數在更新後當即被調用。初始渲染不調用此方法。

  當組件已經更新時,使用此操做做爲DOM操做的機會。這也是一個好的地方作網絡請求,只要你比較當前的props和之前的props(例如:若是props沒有改變,可能不須要網絡請求)。

Unmounting

當從dom中移除組件時,這個方法會被調用

  • componentWillUnmount()
      此函數在組件被卸載和銷燬以前被當即調用。在此方法中執行一些必要的清理。例如清除計時器,取消網絡請求或者清理在componentDidMount中建立的任何DOM元素。

上手試試

官網說組件生命週期是這樣的,可是誰知道對不對呢(固然是對的,可是懷疑的態度仍是要有的嘛,主要仍是爲了加深理解,更好的寫React組件)。

https://codepen.io/NsNe/pen/o...

能夠在http://codepen.io(此處不是打廣告,只是本身在用這款而已,固然你也能夠用其的,好比:jsfiddle等,總有一款適合你,也能夠直接f12(chrome),打開console)查看上述代碼的console結果。
第一次渲染組件:LifeCycle組件第一次渲染時,打印出(生命週期函數執行):

"constructor"
"componentWillMount"
"render"
"componentDidMount"

當組件的props發生改變:當咱們點擊「改變LifeCycle的props」按鈕(組件的props發生改變)時,按理說,這時LifeCycle會調用updating階段的鉤子函數。

"componentWillReceiveProps"
"shouldComponentUpdate"
"componentWillUpdate"
"render"
"componentDidUpdate"

當組件的state發生改變:咱們在組件內部,點擊「改變LifeCycle的state」按鈕時(組件的state發生改變),打印以下

"shouldComponentUpdate"
"componentWillUpdate"
"render"
"componentDidUpdate"

當父組件致使子組件從新渲染:當點擊「父組件從新渲染,子組件re-render」按鈕時(在父組件中改變與子組件無關的state),打印結果以下

"componentWillReceiveProps"
"shouldComponentUpdate"
"componentWillUpdate"
"render"
"componentDidUpdate"

當組件被卸載和銷燬:打印結果以下:

"componentWillUnmount"

結語

  至此,咱們已經很清楚的知道了React組件的生命週期,等到咱們寫組件的時候就會很清楚的知道代碼該往哪裏寫,哪些地方不能setState等等。你們能夠在上述代碼中按本身的意願來修改,加深理解。  文中不免有疏漏,望你們共同交流,批評指正。

相關文章
相關標籤/搜索