組件的生命周期

一共有四個聲明周期init(初始化),mount(裝載),update(更新),unmount(卸載)。只有更新可能會執(zhí)行多次,其余都只執(zhí)行1次。

init
getDefaultProps(生成默認(rèn)屬性):在創(chuàng)建類的時候,React.createclass時指定。是一個共有的,所有的實例都會使用,是針對類而言的,只會調(diào)用一次。
getInitialState(初始化state):ES6時在構(gòu)造函數(shù)中指定。getInitialState針對具體的實例,每個實例生成時都會調(diào)用一次。

const Item = React.createClass({
  getDefaultProps () {
    console.log('getDefaultProps')
    return {
      'group': 'javascript'
    }
  },
  getInitialState () {
    console.log('getInitialState')
    return {
      'name': 'cc'
    }
  },
  render () {
    return <div>{this.state.name + this.props.group}</div>
  }

})
ReactDOM.render(
  <div>
    <Item />
  </div>, document.getElementById('root'))
圖片.png

執(zhí)行的先后順序。當(dāng)調(diào)用多個item時:

ReactDOM.render(
  <div>
    <Item />
    <Item />
    <Item />
  </div>, document.getElementById('root'))
圖片.png

調(diào)用了一次getDefaultProps,三次getInitialState。


mount組件裝載階段:包含預(yù)加載、渲染和加載完畢三個周期,都只執(zhí)行一次。預(yù)加載時dom未成形,不能操作dom。

class Item extends React.Component {
  constructor (props) {
    super(props)
    console.log('getInitialState')
    this.state = {
      'group': 'hello'
    }
  }
  static get defaultProps () {
    console.log('defaultProps')
    return {
      'name': 'cc'
    }
  }
  componentWillMount () {
    console.log('componentWillMount')
    this.state.name = 'cc'
  }
  componentDidMount () {
    console.log('componentDidMount')
  }
  render () {
    console.log('render')
    return <div>{this.state.group + this.props.name}</div>
  }
}

打印順序如下圖


圖片.png

componentWillMount(預(yù)加載),可以操作組件的state,不能操作DOM
componentDidMount(加載完畢),這時可以操作DOM,也可以再此處引入一些外部交互,比如發(fā)送請求,與其他框架交互。
render(渲染),初次渲染,沒什么好說的。


Update:只在組件更新時會觸發(fā),初次加載時不會觸發(fā)。
把上面的代碼頁面渲染部分封裝為render方法:

const Item = React.createClass({
  getDefaultProps () {
    console.log('getDefaultProps')
    return {
      'group': 'javascript'
    }
  },
  getInitialState () {
    console.log('getInitialState')
    return {
      'name': 'cc'
    }
  },
  componentWillMount () {
    console.log('componentWillMount')
    this.state.name = 'cc'
  },
  componentDidMount () {
    console.log('componentDidMount')
  },
  render () {
    console.log('render')
    return <div>{this.state.group + this.props.name}</div>
  },
  componentWillUpdate (nextProps, nextState) {
    console.log('component will update')
  },
  componentDidUpdate (oldProps, oldState) {
    console.log('compontent did update')
  }
})

ReactDOM.render(
    <div>
      <Item />
    </div>, document.getElementById('root'))
圖片.png

初次加載沒有觸發(fā)update,觸發(fā)update有三種方式,外部渲染(如本例中演示),內(nèi)部state變化,外部傳入?yún)?shù)。當(dāng)我們頁面的render方法包裝下。

function render () {
  ReactDOM.render(
    <div>
      <Item />
    </div>, document.getElementById('root'))
}
render()   //調(diào)用兩次render
render()
圖片.png

觸發(fā)了update,而且每次還會自動調(diào)用render。

componentWillUpdate(nextProps,nextState):組件預(yù)更新,接受兩個參數(shù),新的組件props和新的狀態(tài)state;
為了防止組件頻繁刷新,還有一個組件的更新驗證方法shouldComponentUpdate,用于控制組件是否需要更新狀態(tài)。

特殊方法: shouldComponentUpdate (nextProps, nextState) {
    return false//返回false,則組件不會被update
  }
圖片.png

組件加入shouldComponentUpdate 后沒有被update。

特殊方法:componentWillReceiveProps(nextProps)已加載組件收到新的參數(shù)時調(diào)用。componentWillReceiveProps()
當(dāng)一個組件收到新的props時被調(diào)用。如果需要改變狀態(tài)來響應(yīng)props的改變可以先比較傳入的props和當(dāng)前的props,再在此方法內(nèi)調(diào)用setState()來改變state。React可能會調(diào)用這個方法,即使props沒有改變,所以在處理變化時必須在方法內(nèi)比較當(dāng)前值和新的值props。這個可能會因為父元素的變化導(dǎo)致子元素重新渲染。在組件加載過程中不會調(diào)用此方法。只有傳入新的props時才會調(diào)用,同樣setState也不會觸發(fā)此方法。(以上翻自react官網(wǎng)說明)。
unmount卸載階段
componentWillUnmount

在組件被卸載和摧毀前被立即調(diào)用。清理應(yīng)該放在這里。

比如說我在組件的加載時寫了個setInterval定時器,在路由router跳轉(zhuǎn)后,我們應(yīng)該要clearInterval這個定時器,不然是很耗性能的,包括我們的全局事件綁定,都需要在這里取消。
.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容