React16.3.0開始,生命週期進行了一些變化。本文主要介紹React16.3.0之後的生命週期。
React16.3.0之前生命週期:
16版本之前的react元件的生命週期相信大家已經很熟悉。16版本的react對元件的生命週期函式進行了一些修改,下面進行詳細說明。
React16.3.0之前生命週期
建立期:
- constructor(props, context)
- componentWillMount()
- render()
- componentDidMount()
執行時:
props發生變化時
- componentWillReceiveProps(nextProps, nextContext)
- shouldComponentUpdate(nextProps, nextState, nextContext)
- componentWillUpdate(nextProps, nextState, nextContext)
- render
- componentDidUpdate(prevProps, prevState, snapshot)
state發生變化時
- shouldComponentUpdate(nextProps, nextState, nextContext)
- componentWillUpdate(nextProps, nextState, nextContext)
- render
- componentDidUpdate(prevProps, prevState, snapshot)
解除安裝時
componentWillUnmount()
React16.3.0之後的生命週期
建立期:
- constructor(props, context)
- static getDerivedStateFromProps(props, status)
- render()
- componentDidMount()
或者如下生命週期:
- constructor(props, context)
- componentWillMount() / UNSAFE_componentWillMount()
- render()
- componentDidMount()
注意: getDerivedStateFromProps/getSnapshotBeforeUpdate 和 componentWillMount/componentWillReceiveProps/componentWillUpdate 如果同時存在,React會在控制檯給出警告資訊,且僅執行 getDerivedStateFromProps/getSnapshotBeforeUpdate 【React@16.7.0】
執行時:
props發生變化時
- static getDerivedStateFromProps(props, status)
- shouldComponentUpdate(nextProps, nextState, nextContext)
- render
- getSnapshotBeforeUpdate(prevProps, prevState)
- componentDidUpdate(prevProps, prevState, snapshot)
或者如下生命週期:
- componentWillReceiveProps(nextProps, nextContext)/UNSAFE_componentWillReceiveProps
- shouldComponentUpdate(nextProps, nextState, nextContext)
- componentWillUpdate(nextProps, nextState, nextContext)
- render
- componentDidUpdate(prevProps, prevState, snapshot)
state發生變化時
- static getDerivedStateFromProps(props, status)
- shouldComponentUpdate(nextProps, nextState, nextContext)
- render
- getSnapshotBeforeUpdate(prevProps, prevState)
- componentDidUpdate(prevProps, prevState, snapshot)
或者如下生命週期:
- shouldComponentUpdate(nextProps, nextState, nextContext)
- componentWillUpdate(nextProps, nextState, nextContext)/UNSAFE_componentWillUpdate
- render
- componentDidUpdate(prevProps, prevState, snapshot)
銷燬時
componentWillUnmount()
新的生命週期圖示:
生命週期詳解
1.constructor(props, context)
constructor生命週期,如不需要,可預設。通常會在 constructor 方法中初始化 state 和繫結事件處理程式。 但是,如果寫了constructor,那麼必須在其中呼叫super(props);否則可能會引起報錯。
如:
class Base extends Component {
constructor(props) {
super(); //應該為 super(props);
}
state = {
name: this.props.name
}
//....code
}
複製程式碼
丟擲異常: Uncaught TypeError: Cannot read property 'name' of undefined.
同樣,如果定義了context,在state中需要使用this.context去獲取context上的內容,則需要super(props, context);
不過,如果你預設constructor,那麼在state中,可以放心的使用 this.props 或者是 this.context,不會引起報錯。
class Base extends Component {
state = {
name: this.props.name,
color: this.context.color
}
//....code
}
複製程式碼
初始化的state同樣可以在constructor中定義。如果需要給方法繫結this,那麼統一在constructor中進行。
2.static getDerivedStateFromProps(props, state)
當元件的state需要根據props來改變的時候可呼叫此方法。這個方法是在 render() 前會被執行,每次觸發render前,都會觸發此方法。
該方法有兩個引數props和state; 返回值為state物件, 不需要返回整體state,把需要改變的state返回即可。如果不需要,可以返回null.
class Base extends Component {
state = {
age: 20
}
static getDerivedStateFromProps(props, state) {
return {
age: 50
}
}
render() {
// 50
return (
<div>{this.state.age}</div>
)
}
}
複製程式碼
這個方法允許元件基於 props 的變更來更新其內部狀態,以這種方式獲得的元件狀態被稱為派生狀態。應該謹慎使用派生狀態,可能會引入潛在的錯誤
3.render
React元件中必須要提供的方法。當state或者props任一資料有更新時都會執行。
render() 是一個純函式,因此,不要在其中執行setState諸如此類的操作。render必須有一個返回值,返回的資料型別可以有:
- null、String、Number、Array、Boolean。
- React elements
- Fragment
- Portal
注意不要在render中呼叫setState
4.componentDidMount
componentDidMount()方法是在元件載入完後立即執行,也就是當該元件相關的dom節點插入到dom樹中時。該方法在元件生命中只執行一次。 一般情況,我們會在這裡setState(),或者進行介面請求,設定訂閱等。
class Base extends Component {
state = {
age: 20
}
componentDidMount() {
this.fetchDate();
}
render() {
return (
<div>{this.state.age}</div>
)
}
//other code
}
複製程式碼
5.shouldComponentUpdate(nextProps, nextState, nextContext)
在渲染新的props或state前,shouldComponentUpdate被呼叫,預設返回true。forceUpdate()時不會呼叫此方法。
如果shouldComponentUpdate()返回false,那麼getSnapshotBeforeUpdate,render和componentDidUpdate不會被呼叫。
此生命週期主要用於優化效能。
6.getSnapshotBeforeUpdate(prevProps, prevState)
在render()的輸出被渲染到DOM之前被呼叫。使元件能夠在它們被更改之前捕獲當前值(如滾動位置)。這個生命週期返回的任何值都將作為第三個引數傳遞給componentDidUpdate().
7.componentDidUpdate(prevProps, prevState, snapshot)
在更新發生後呼叫 componentDidUpdate()。當元件更新時,將此作為一個機會來操作DOM。如將當前的props與以前的props進行比較(例如,如果props沒有改變,則可能不需要網路請求。
如果元件使用 getSnapshotBeforeUpdate(),則它返回的值將作為第三個“快照”引數傳遞給 componentDidUpdate()。否則,這個引數是undefined。
8.componentWillUnmount()
在元件被解除安裝並銷燬之前立即被呼叫。在此方法中執行任何必要的清理,例如使定時器無效,取消網路請求或清理在componentDidMount()中建立的任何監聽。
最後,說明一點:
componentWillUpdate,componentWillReceiveProps,componentWillUpdate這三個生命週期在React未來版本中會被廢棄。
而UNSAFE_componentWillUpdate,UNSAFE_componentWillReceiveProps,UNSAFE_componentWillUpdate 未來版本中仍可繼續使用。
初始化階段(父元件和子元件):
執行階段:父元件props/state更新
子元件的shouldComponentUpdate返回false,則子元件其後的生命週期都不在進行,但是父元件的生命週期繼續執行。
解除安裝階段: 解除安裝父元件
參考:
更多博文閱讀,請移步(歡迎Star呀): github.com/YvetteLau/B…