爲了進一步瞭解React的工做過程,已經曉得了怎麼編寫React組件,知道了React的數據流,那麼是時候學習React組件的生命週期了,每一個組件都包含生命週期方法,生命週期如同四季更替,一我的的生,老,病,死.在每一個特殊的年齡階段,作着不一樣的事情javascript
在React編寫組件中,一樣,每一個組件在網頁中都有被建立,更新,刪除這麼一過程,就像有機的生命體同樣java
理解生命週期函數對於編寫React組件代碼是很是重要的react
若是你不清楚生命週期,以及生命週期的應用場景,那麼本篇就是你想要知道的瀏覽器
生命週期(鉤子)函數
定義: 在特定的階段,可以自動執行的函數(方法)服務器
在前面的JSX學習中,一個React元素渲染到頁面當中,本質上是經過底層的React.CreateElement的一個方法實現的,它是一個javascript對象,將虛擬DOM轉化爲真實的DOM,最後經過ReactDOM.render()方法將真實的DOM渲染掛載到對應的頁面位置上網絡
一個組件的渲染,經歷瞭如下幾個過程:能夠對照這個生命週期圖譜的 dom
三種不一樣的過程,React庫會依次調用組件的一些成員函數(生命週期函數)異步
裝載過程
當組件第一次被渲染的時候,會依次的調用以下生命週期函數函數
使用場景:當組件內部的state變化依賴於props時,調用該生命週期函數 注意:不要過分使用該函數,若是你的操做依賴於props的更改並有反作用,最好放到componentDidUpdate中
它也只會在初始化的時候調用一次,因此this壞境的綁定放在這裏面也是能夠的,可是最好是放在constructor構造器函數裏面,若是是處理帶有後續異步操做或者有反作用的訂閱事件處理,例如:Ajax數據獲取,則放到componentDidMount中
constructor:構造器函數
constructor(ptops) {
super(props); // 必定要調用super,而且接收props參數,不然該組件的實例方法沒法獲取到外部的props值
}
複製代碼
至於constructor在上節當中已經說起過,並非每一個組件都須要定義constructor構造器函數,函數式(無狀態)組件就不須要定義構造函數
通常使用constructor構造函數有以下兩種狀況
爲了方便調用,在構造函數中,this就是當前組件的實例,每每在構造函數中將組件實例下的成員方法綁定this爲當前的實例對象
constructor(props){
super(props);
}
// 事件監聽處理函數,this壞境的綁定
this.handleBtnClick = this.handleBtnCLick.bind(this);
this.handleInputChange = this.handleInputChange.bind(this)
複製代碼
在執行了constructor構造器函數後,執行componentWillMount方法,而後在執行render方法,執行完render方法後,在執行componentDidMount方法,整個裝載過程就結束了的
固然這其中的一個componentWillUnmount方法是在組件銷燬前進行觸發,也就是刪除DOM元素以前調用,這個經常使用於當組件從頁面刪除銷燬時,作一些數據清理的時候能用得上,例如定時器的清理,取消網絡請求,在該生命週期函數內,不該該調用setState函數,由於該組件銷燬後,將不會被從新渲染
具體的實例代碼以下所示:
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
class LifeCycle extends Component {
constructor(props){
super(props);
console.log("1-constructor函數被調用執行");
this.state = {
isShow: true
}
this.handleBtnClick = this.handleBtnClick.bind(this);
}
componentWillMount(){
console.log("2-componentWillMount函數已執行,組件掛載以前,在render方法以前調用", this.state.isShow);
}
componentDidMount() {
console.log("4-componentDidMount函數已執行,組件掛載完以後,DOM元素已經插入到頁面後調用");
}
render(){
console.log("3-render函數執行");
return (
<Fragment>
<div>
{ this.state.isShow? <Text />:""}
<button onClick={ this.handleBtnClick }>更改</button>
</div>
</Fragment>
);
}
handleBtnClick(){
this.setState({
isShow:!this.state.isShow
})
}
}
class Text extends Component {
componentWillUnmount(){
console.log("componentWillUnmount函數已執行,組件從頁面中移除以前調用,Text組件移除");
}
render(){
console.log("Text組件被渲染");
return (
<h1>itclanCoder</h1>
);
}
}
const container = document.getElementById('root');
ReactDOM.render(<LifeCycle />, container);
複製代碼
效果以下所示:
你們能夠自行將這些生命週期函數放到組件內部當中,進行測試的,看每一個生命週期執行的順序就一目瞭然了的
說完了組件的裝載,那麼接下來就是組件的更新了
組件的更新
當props或者state發生改變的時候,就會引發render函數的渲染,也就是會引起組件的更新,它與組件的裝載同樣,會觸發一些生命週期函數
更新組件時:生命週期函數執行的順序
你能夠理解爲,第一次渲染時,父組件的componentWillReceiveProps函數不會被執行,若是是第二次渲染時,已經存在於父組件中,則該componentWillReceiveProps纔會執行
注意:在掛載過程當中,React不會針對初始props調用此方法,經過觸發setState方法更新過程不會調用這個函數,這是由於這個函數適合根據新的props值(也就是nextProps)來計算出是否是要更新內部狀態state
應用場景:當你但願只有在接收新的props時作一些邏輯時,props改變須要相應改變內部state狀態時,則使用componentWillReceiveProps,好比:根據父組件傳入的數據初始化或重置組件內部的某些state狀態
返回一個boolean值,告訴React庫這個組件在此次更新過程是否要繼續,若是該函數返回true,那麼繼續更新,調用render函數,反之,若函數返回false,那麼馬上中止更新過程,便不會執行render函數了的
這個函數是提升React的性能的,若是發現不必的渲染,那就乾脆不用渲染了的,這個shouldComponentUpdate就能夠作到
注意: forceUpdate不會觸發該函數,也可使用PureComponent替代該函數,該函數作了內部的優化
// nextProps表示的是接下來個人props值會樣,nextState表示的是個人state會變成什麼樣
shouldComponentUpdate(nextProps, nextState)
if(nextProps.props屬性 !== this.props.props屬性 || nextState.state屬性 !== this.state.state屬性)
return true;
}else{
return false
}
複製代碼
注意: 不要在該函數中經過this.setState再次改變state,若是須要,則在componentWillReceiveProps函數中改變
注意:不能在render函數中調用setState,若是在shouldComponentUpdate返回false,則render函數不會被調用
應用場景:若是但願不管props更改仍是組件內的狀態更改都能觸發一些邏輯,則可使用componentDidUpdate,進行業務處理,發送網絡請求
注意:在處理業務或發送網絡請求時,必定要作好條件比較,不然容易形成死循環
組件的卸載
React組件從頁面中移除時,在卸載的過程當中,只涉及一個生命週期函數componentWillUnmount,因爲該函數在組件刪除以前會被調用,因此該函數適合作一些清理性的工做
應用場景: 清理無效的timer,取消未完成的網絡請求,清理已註冊的訂閱
注意:在這裏使用setState時無效的
固然對於React的生命週期,不一樣的版本,官方對它作了一些優化和改動,這裏介紹的是React Version 16.2.0版本的,生命週期過程圖以下所示
若是是最新的,在React17.0版本中,生命週期函數以下所示
本文主要講解了React的生命週期,只要理解了生命週期的圖譜,生命週期也就差很少了的,在constructor構造器中初始化工做,componentWillMount在組件即將掛載以前執行調用,經常使用於組件的啓動工做,例如:Ajax數據的獲取,定時器的啓動
固然數據的請求最好放在componentDidMount函數中,而當props或者state發生改變時,會引發組件的渲染,也就是組件的更新,只要父組件的render函數被渲染了,就會觸發子組件的componentWillReceiveProps,而當shouldComponentUpdate的函數返回true時,則render函數會渲染,要是返回false時,則render函數不會渲染
當組件從頁面中移除時,在卸載以前會觸發componentWillUnmount函數,該函數經常用於組件銷燬時調用,清理無效的定時器timer,取消未完成的網絡(Ajax)請求,清理已註冊的訂閱