constructor
React借用class
類的constructor
充當初始化鉤子仔夺。在我們類擴展任何其他具有已定義構(gòu)造函數(shù)的類的情況下,調(diào)用一個特殊的函數(shù)super
非常重要忆植。
在React
中挡鞍,因為所有class
組件都要繼承自Component
類或者PureComponent
類,因此和原生class寫法一樣历葛,要在constructor里首先調(diào)用super
方法,才能獲得this
嘀略。
deprecated—componentWillMount
componentWillMount
與構(gòu)造函數(shù)沒有太大的區(qū)別——它也只在初始安裝生命周期中調(diào)用一次恤溶。
許多人會在這個函數(shù)中發(fā)送請求來獲取數(shù)據(jù),并期望在初次渲染就緒之前數(shù)據(jù)是可用的帜羊。
事實并非如此宏娄,盡管請求將在初次渲染之前被初始化,但在有時調(diào)用render
之前它無法完成逮壁。
由于這一事實,不建議使用此函數(shù)可能會導致操作的副作用粮宛。
需要注意的是窥淆,在服務(wù)端渲染時調(diào)用此函數(shù),而在這種情況下巍杈,不會在服務(wù)器上調(diào)用對應(yīng)的componentDidMount忧饭,而是在客戶端上調(diào)用。
在這個函數(shù)中使用setState
不會觸發(fā)render
static getDerivedStateFromProps(nextProps, prevState)
這個新的方法根據(jù)父組件傳來的props按需更新自己的state筷畦,主要是來代替componentWillReceiveProps
词裤。
該方法定義的時候要加一個static
關(guān)鍵字,訪問不到this
對象鳖宾,在使用的時候吼砂,返回一個對象來增量更新組件的state
(和setState
非常像)
render
千萬不要在render
生命周期鉤子里調(diào)用setState
,因為setState
會引發(fā)render
鼎文,這樣就沒完沒了渔肩。
componentDidMount
在組件掛載之后調(diào)用,并且只調(diào)用一次拇惋。
因為這個函數(shù)只保證被調(diào)用一次周偎,所以它在這里執(zhí)行ajax
請求簡直是完美。
deprecated—componentWillReceiveProps(nextProps)
在每次收到props
(父組件重新渲染)的時候撑帖,在每個更新生命周期中都會調(diào)用此函數(shù)蓉坎,而且會傳遞所有的props
,無論props
的值是否發(fā)生了改變胡嘿,簡單來說就是組件收到新的props
或者父組件重新渲染蛉艾,都會觸發(fā)這個方法。
如果某個組件的部分state
是依賴于父組件中傳遞過來的props
,這個函數(shù)是理想的伺通。
- 注意:即使
props
沒有發(fā)生變化箍土,在componentWillReceiveProps
也會被調(diào)用,這就需要開發(fā)者來判斷其值是否已經(jīng)發(fā)生改變罐监。
componentWillReceiveProps(nextProps) {
if(nextProps.myProp !== this.props.myProps) {
// do something
}
}
shouldComponentUpdate(nextProps, nextState, nextContext)
默認情況下吴藻,所有基于Components
的類在收到props
時,state
或context
改變時弓柱,都會觸發(fā)render
沟堡。如果重新渲染組件涉及的計算比較復雜(比如生成圖表)或者由于某些性能原因而不推薦,則開發(fā)人員就需要來控制一下了矢空。當shouldComponentUpdate
返回false
的時候航罗,就不會觸發(fā)render
。
React
還提供了一個PureComponent
屁药,它與Component
的區(qū)別是PureComponent
自動實現(xiàn)了一個shouldComponentUpdate
粥血。
shouldComponentUpdate
暴露了兩個參數(shù),開發(fā)者可以通過比較props
和nextProps
酿箭、state
和nextState
來判斷狀態(tài)到底有沒有發(fā)生改變复亏,再返回true
或false
。要注意一下引用的坑缭嫡。
deprecated — componentWillUpdate(nextProps, nextState)
shouldComponentUpdate
生命周期鉤子返回true缔御,或者調(diào)用this.forceUpdate之后,會立即執(zhí)行該生命周期鉤子妇蛀。
要特別注意耕突,componentWillUpdate
生命周期鉤子每次更新前都會執(zhí)行,所以不能在這里調(diào)用setState
评架,有可能會沒完沒了眷茁。
同樣,因為Fiber機制的引入纵诞,這個生命周期鉤子有可能會多次調(diào)用蔼卡。
componentDidUpdate(nextProps, nextState, snapshot)
componentWillUnmount
這是組件卸載之前的生命周期鉤子。
React的最佳實踐是挣磨,組件中用到的事件監(jiān)聽器雇逞、訂閱器、定時器都要在這里銷毀茁裙。
componentDidMount() {
document.addEventListener('click', () => {});
}
componentDidCatch
在過去塘砸,組件內(nèi)部的JavaScript錯誤總是擾亂組件狀態(tài)以至于在下一次渲染中出現(xiàn)一些奇怪的錯誤,而且這些錯誤常常由應(yīng)用中一些更早的錯誤引起晤锥,然而 React 沒有提供一種在組件內(nèi)部解決這些問題的優(yōu)雅方案掉蔬,也不能從錯誤中恢復廊宪。
用戶界面某處的 JavaScript 錯誤不應(yīng)該使整個 APP 崩潰,為了解決這個問題女轿,React16 引進了一個新的概念 —— Error Boundaries
Error Boundaries 可以捕獲在其子組件樹里拋出的任何錯誤箭启,打印這些錯誤,并且返回一個展示錯誤的界面而不是崩潰掉的頁面蛉迹。Error Boundaries 可以在渲染過程中傅寡、在生命周期方法中、以及其子組件的 constructor 中捕獲錯誤
添加了一個叫做 componentDidCatch(error, info)
的新生命周期方法的組件就叫做 Error Boundaries
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
你仍然可以像正常組件一樣使用它
<ErrorBoundary>
<App />
</ErrorBoundary>
componentDidCatch()
方法就像是為組件定制的 JavaScript 中的 catch {} 代碼塊北救,只有通過 class 定義的組件才能成為 Error Boundaries荐操,在實踐中,絕大多數(shù)時候你都希望只定義一個 Error Boundary 然后在應(yīng)用的里使用珍策。
生命周期
React
的生命周期鉤子托启,實際上只有三個過程:
- 掛載
- 更新
- 卸載
老生命周期
-
掛載
- constructor
- componentWillMount
- render
-
componentDidMount
-
更新
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
-
componentDidUpdate
-
卸載
- componentWillUnmount
新生命周期
- 掛載
- constructor
- componentWillMount
- render
- componentDidMount
- 更新
-
static
getDerivedStateFromProps - shouldComponentUpdate
- render
- componentDidUpdate
-
- 卸載
-
componentWillUnmount
-
最后借一下大佬的圖。