前言
如果將React的生命週期比喻成一隻螞蟻爬過一根吊繩,那麼這隻螞蟻從繩頭爬到繩尾,就會依次觸動不同的卡片掛鉤。在React每一個生命週期中,也有類似卡片掛鉤的存在,我們把它稱之為‘鉤子函式’。那麼在React的生命週期中,到底有哪些鉤子函式?React的生命週期又是怎樣的流程?今天我給大家來總結總結
React 生命週期
如圖,React生命週期主要包括三個階段:初始化階段、執行中階段和銷燬階段,在React不同的生命週期裡,會依次觸發不同的鉤子函式,下面我們就來詳細介紹一下React的生命週期函式
一、初始化階段
1、設定元件的預設屬性
static defaultProps = {
name: 'sls',
age:23
};
//or
Counter.defaltProps={name:'sls'}
複製程式碼
2、設定元件的初始化狀態
constructor() {
super();
this.state = {number: 0}
}
複製程式碼
3、componentWillMount()
元件即將被渲染到頁面之前觸發,此時可以進行開啟定時器、向伺服器傳送請求等操作
4、render()
元件渲染
5、componentDidMount()
元件已經被渲染到頁面中後觸發:此時頁面中有了真正的DOM的元素,可以進行DOM相關的操作
二、執行中階段
1、componentWillReceiveProps()
元件接收到屬性時觸發
2、shouldComponentUpdate()
當元件接收到新屬性,或者元件的狀態發生改變時觸發。元件首次渲染時並不會觸發
shouldComponentUpdate(newProps, newState) {
if (newProps.number < 5) return true;
return false
}
//該鉤子函式可以接收到兩個引數,新的屬性和狀態,返回true/false來控制元件是否需要更新。
複製程式碼
一般我們通過該函式來優化效能:
一個React專案需要更新一個小元件時,很可能需要父元件更新自己的狀態。而一個父元件的重新更新會造成它旗下所有的子元件重新執行render()方法,形成新的虛擬DOM,再用diff演算法對新舊虛擬DOM進行結構和屬性的比較,決定元件是否需要重新渲染
無疑這樣的操作會造成很多的效能浪費,所以我們開發者可以根據專案的業務邏輯,在
shouldComponentUpdate()
中加入條件判斷,從而優化效能
例如React中的就提供了一個
PureComponent
的類,當我們的元件繼承於它時,元件更新時就會預設先比較新舊屬性和狀態,從而決定元件是否更新。值得注意的是,PureComponent
進行的是淺比較,所以元件狀態或屬性改變時,都需要返回一個新的物件或陣列
3、componentWillUpdate()
元件即將被更新時觸發
4、componentDidUpdate()
元件被更新完成後觸發。頁面中產生了新的DOM的元素,可以進行DOM操作
三、銷燬階段
1、componentWillUnmount()
元件被銷燬時觸發。這裡我們可以進行一些清理操作,例如清理定時器,取消Redux的訂閱事件等等。
有興趣的同學也可以用下面的程式碼進行測試
廢話少說,放碼過來!
import React from 'react'
import ReactDOM from 'react-dom';
class SubCounter extends React.Component {
componentWillReceiveProps() {
console.log('9、子元件將要接收到新屬性');
}
shouldComponentUpdate(newProps, newState) {
console.log('10、子元件是否需要更新');
if (newProps.number < 5) return true;
return false
}
componentWillUpdate() {
console.log('11、子元件將要更新');
}
componentDidUpdate() {
console.log('13、子元件更新完成');
}
componentWillUnmount() {
console.log('14、子元件將解除安裝');
}
render() {
console.log('12、子元件掛載中');
return (
<p>{this.props.number}</p>
)
}
}
class Counter extends React.Component {
static defaultProps = {
//1、載入預設屬性
name: 'sls',
age:23
};
constructor() {
super();
//2、載入預設狀態
this.state = {number: 0}
}
componentWillMount() {
console.log('3、父元件掛載之前');
}
componentDidMount() {
console.log('5、父元件掛載完成');
}
shouldComponentUpdate(newProps, newState) {
console.log('6、父元件是否需要更新');
if (newState.number<15) return true;
return false
}
componentWillUpdate() {
console.log('7、父元件將要更新');
}
componentDidUpdate() {
console.log('8、父元件更新完成');
}
handleClick = () => {
this.setState({
number: this.state.number + 1
})
};
render() {
console.log('4、render(父元件掛載)');
return (
<div>
<p>{this.state.number}</p>
<button onClick={this.handleClick}>+</button>
{this.state.number<10?<SubCounter number={this.state.number}/>:null}
</div>
)
}
}
ReactDOM.render(<Counter/>, document.getElementById('root'));
複製程式碼