React組件生命週期

React組件的生命週期有一堆的相關函數,其實就是一推的鉤子函數。在React組件建立的各個階段觸發特定的鉤子函數。react

能夠先大概看一下下面這張圖:
圖片描述安全

constructor

構造函數,在建立組件的時候調用一次。服務器

constructor(props, context)

componentWillMount

在組件掛載以前調用一次。若是在這個函數裏面調用setState,render()知道state發生變化,而且只渲染一次。網絡

void componentWillMount()

render

render是一個React組件所必不可少的核心函數。不要在render裏面修改state。也不要去讀寫DOM或者與服務器交互,保持render()方法的純淨。app

ReactElement render()

componentDidMount

在組件掛載以後調用一次。這個時候,子組件也都掛載好了,能夠在這裏使用refs。dom

void componentDidMount()

shouldComponentUpdate

這個方法在初始化render時不會執行,當props或者state發生變化時執行。函數默認返回true,須要從新render。返回false,就不會從新render了。componentWillUpdate和componentDidUpdate方法也不會被調用。在比較複雜的應用裏,有一些數據的改變並不影響界面展現,能夠在這裏作判斷,優化渲染效率。函數

boolean shouldComponentUpdate(
    object nextProps, object nextState
)

componentWillUpdate

shouldComponentUpdate返回true以後,componentWillUpdate會被調用。須要特別注意的是,在這個函數裏面,不要用this.setState來修改狀態。否則這個函數會無限循環執行。這個函數調用以後,就會把nextProps和nextState分別設置到this.props和this.state中。緊接着這個函數,就會調用render()來更新界面了。測試

void componentWillUpdate(
  object nextProps, object nextState
)

componentDidUpdate

除了首次render以後調用componentDidMount,其它render結束以後都是調用componentDidUpdate。優化

void componentDidUpdate()

componentWillReceiveProps

props是父組件傳遞給子組件的。父組件發生render的時候子組件就會調用componentWillReceiveProps(無論props有沒有更新,也無論父子組件之間有沒有數據交換)。在這個回調函數裏面,你能夠根據屬性的變化,經過調用this.setState()來更新你的組件狀態,舊的屬性仍是能夠經過this.props來獲取,這裏調用更新狀態是安全的,並不會觸發額外的render調用。ui

void componentWillReceiveProps(nextProps) {
    this.setState({...});
}

componentWillUnmount

當組件要被從界面上移除的時候,就會調用componentWillUnmount(),在這個函數中,能夠作一些組件相關的清理工做,例如取消計時器、網絡請求等。

void componentWillUnmount()

下面是一個React組件生命週期的測試例子

var React = require('react');
var ReactDOM = require('react-dom');

class Parent extends React.Component {
  constructor(){
    super()
    console.log("%cparent -- constructor","color:green");
    this.state = {
      name : 'Lucy'
    }
  }

  componentWillMount(){
    console.log("%cparent -- componentWillMount","color:green");
  }

  componentDidMount(){
    console.log("%cparent -- componentDidMount","color:green");
  }

  componentWillReceiveProps(){
    console.log("%cparent -- componentWillReceiveProps","color:green");
  }

  shouldComponentUpdate(){
    console.log("%cparent -- shouldComponentUpdate","color:green");
    return true;
  }

  componentWillUpdate(){
    console.log("%cparent -- componentWillUpdate","color:green");
  }

  componentDidUpdate(){
    console.log("%cparent -- componentDidUpdate","color:green");
  }

  componentWillUnmount(){
    console.log("%cparent -- componentWillUnmount","color:green");
  }

  changeName(){
    this.setState({name : 'Jone'})
  }

  unmountComponent(){
    ReactDOM.unmountComponentAtNode(document.getElementById("app"));
  }

  render(){
    console.log("%cparent -- render","color:green");
    return(
      <div style={{border:'1px solid #000',color:'green'}}>
        <h2>Parent:</h2>
        <h3>hello {this.state.name}</h3>
        <button onClick={this.changeName.bind(this)}>state改變</button>
        <button onClick={this.unmountComponent.bind(this)}>卸載組件</button>
        <Child props1="haha"></Child>
      </div>
    )
  }
}


class Child extends React.Component {
  constructor(){
    super()
    console.log("  %cchild -- constructor","color:blue");
    this.state = {
    }
  }

  componentWillMount(){
    console.log("  %cchild -- componentWillMount","color:blue");
  }

  componentDidMount(){
    console.log("  %cchild -- componentDidMount","color:blue");
  }

  componentWillReceiveProps(){
    console.log("  %cchild -- componentWillReceiveProps","color:blue");
  }

  shouldComponentUpdate(){
    console.log("  %cchild -- shouldComponentUpdate","color:blue");
    return true;
  }

  componentWillUpdate(){
    console.log("  %cchild -- componentWillUpdate","color:blue");
  }

  componentDidUpdate(){
    console.log("  %cchild -- componentDidUpdate","color:blue");
  }

  componentWillUnmount(){
    console.log("  %cchild -- componentWillUnmount","color:blue");
  }

  changeName(){
    this.setState({name : 'Jone'})
  }

  render(){
    console.log("  %cchild -- render","color:blue");
    return(
      <div style={{border:'1px solid #000',margin:'10px',color:'blue'}}>
        <h2>Child:</h2>
      </div>
    )
  }
}

ReactDOM.render(
  <Parent></Parent>,
  document.getElementById('app')
);

測試例子截圖以下:

圖片描述

改變父組件的state:
圖片描述

卸載組件後:
圖片描述

相關文章
相關標籤/搜索