前言:React 的版本從 v15 到 v16.3 ,再到v16.4,如今最新的版本是 v16.8了。其中最大的變化多是React Hooks
的加入,而最使人困惑的倒是它的生命週期,新舊生命週期函數混雜在一塊兒,不免會讓許多新來者有不少困惑。因此這一篇咱們來分析一下 React 生命週期的演變及緣由,進一步理解其使用。react
這些方法會在組件初始化的時候被調用,只跟實例的建立有關。
若是用createReactClass
進行建立,則還有getInitialState
這些生命週期函數,但不多使用,咱們這裏不說起。算法
定義默認props
,會和父組件傳下來的props
進行合併,且以父組件中的props
優先級更高,至關於{...defaultProps, props}
。segmentfault
定義props
的數據類型,能夠幫助咱們肯定其有效性,減小許多開發中沒必要要的錯誤。瀏覽器
在加載階段前調用一次,進行 state 的初始化。性能優化
constructor(props){ super(props) }
super(props)
用來調用父類的構建方法。網絡
新版中爲UNSAFE_componentWillMount()
。dom
只在組件加載時調用,整個生命週期只調用一次,之後組件更新也不會調用,此時能夠修改 state。async
react
中最重要的生命週期函數,建立虛擬 dom,並進行 diff
算法,更新 dom 樹也在此進行。因此不該該在此改變組件的狀態或者與瀏覽器進行交互。ide
注意:這個函數不能缺乏,若是不建立虛擬 dom,能夠return null
。函數
組件加載完成後當即調用,整個生命週期只調用一次,能夠獲取到更新後的 DOM,在此處能夠進行網絡請求等。
新版中爲UNSAFE_componentWillReceiveProps()
。
在組件加載後,若是有新的props
傳遞過來,會先調用這個函數,能夠在這裏調用setState()
修改state
。
componentWillReceiveProps(nextProps)
react
中一個重要的性能優化點,組件接收到新的props
或者state
,返回true
表示須要更新 dom,返回false
阻止更新。
shouldComponentUpdate(nextProps, nextState)
新版中爲UNSAFE_componentWillUpdate()
。
組件加載時不調用,只有在組件須要更新(即shouldComponentUpdate
返回true
)時調用。
componentWillUpdate(nextProps, nextState)
注意:不能在這個方法中調用setState()
修改state
。
同上。
在組件更新完成後當即被調用,能夠進行網絡請求等。
componentDidUpdate(prevProps, prevState)
在組件被卸載和銷燬以前調用,能夠在這裏處理任何須要的清理工做,好比解除定時器,取消已經發起的網絡請求,清理在componentDidMount
函數中建立的 DOM 元素。
componentWillUnmount()
錯誤邊界捕獲,在v16.0剛推出的時候新增長的一個生命週期函數,用於捕獲在子組件樹中任意地方發生的 JavaScript 錯誤,一個錯誤邊界不能捕獲它本身內部的錯誤。
componentDidCatch(error, info)
import React, {Component} from 'React' export default class OldReactComponent extends Componet{ static defaultProps={} static propTypes={} constructor(props){ super(props) } state={} componentWillMount(){} render(){ return null } componentDidMount(){} componentWillReceivePorps(nextProps){} componentShouldUpdate(nextProps,nextState){ return true } componentWillUpdate(nextProps,nextState){} componentDidUpdate(){} componentWillUnmount(){} }
(帶UNSAFE_
的函數在之後將會被丟棄,官方也不建議使用,這裏再也不列出。)
新版本中,新增了三個生命週期函數:
同時deprecate了一組生命週期API,包括:
能夠看出除了shouldComponentUpdate
以外,render
以前的全部生命週期都被消滅了。緣由是這些生命週期太多時候沒有被正確使用,並且在Fiber
以後,若是要開啓async rendering
,在render
函數以前的全部函數,都有可能被執行屢次。
同上。
由於是靜態方法,因此沒法訪問到組件實例。每次組件調用render
前都會被調用,獲取新的props
和state
(v16.3只會爲props
的而調用,v16.4修正爲props
和state
)以後,返回一個對象做爲新的state
,若是返回null
則表示不須要更新;配合componentDidUpdate,能夠覆蓋componentWillReceiveProps的全部用法。而且它應該是個純函數,沒有反作用(side effect)。
static getDerivedStateFromProps(props,state)
同上。
同上。
同上。
同上。
同上。
觸發時間: update發生的時候,在render以後,在組件dom渲染以前;返回一個值,做爲componentDidUpdate的第三個參數;配合componentDidUpdate, 能夠覆蓋componentWillUpdate的全部用法,經常使用於 scroll 位置的定位。
getSnapshotBeforeUpdate(prevProps, prevState)
同上。
同上。
同上。
用於在「render」階段(非render
函數)的錯誤捕獲,應該是個純函數,沒有反作用(side effect)。
static getDerivedStateFromError(error)
import React, {Component} from 'React' export default class OldReactComponent extends Componet{ static defaultProps={} static propTypes={} constructor(props){ super(props) } state={} static getDerivedStateFromProps(props,state){} render(){ return null } componentDidMount(){} componentShouldUpdate(nextProps,nextState){ return true } getSnapshotBeforeUpdate(prevProps, prevState){} componentDidUpdate(){} componentWillUnmount(){} }
static getDerivedStateFromProps
、getSnapshotBeforeUpdate
並棄用componentWillMount
,componentWillReceiveProps
,componetWillUpdate
(這三個函數將在 React 17中刪除)。static getDerivedStateFromError
捕獲「render」階段的錯誤。幫你理清React的生命週期
清晰大圖請點擊這裏