componentWillMount
1 .在渲染之前調(diào)用柑蛇,在客戶端也在服務(wù)器端
2 .正確調(diào)用的時(shí)候是在component第一次render之前, 所以第一眼看上去覺(jué)得就應(yīng)該在這里去fetch datas.
3 .但是這里有個(gè)問(wèn)題, 在異步請(qǐng)求數(shù)據(jù)中這一次返回的是空數(shù)據(jù), 因?yàn)槭窃凇痳ender’之前不會(huì)返回?cái)?shù)據(jù). 所以在渲染的時(shí)候沒(méi)有辦法等到數(shù)據(jù)到來(lái),也不能在componentWillMount中返回一個(gè)Promise(因?yàn)镻romise的特性之一就是狀態(tài)不可變),或者用setTimeout也是不適合的.正確的處理方式就不要在這里請(qǐng)求數(shù)據(jù),而是讓組件的狀態(tài)在這里正確的初始化.
4 .這個(gè)函數(shù)會(huì)在render之前調(diào)用
5 .constructor函數(shù)和componentWillMount是通用的作用,所以你在構(gòu)造函數(shù)里初始化了組件的狀態(tài)就不必在WillMount做重復(fù)的事情了
6 .服務(wù)端渲染的時(shí)候用這個(gè)生命周期
7 .這里setState不會(huì)觸發(fā)重新渲染
8 .通常推薦使用constructor方法代替
9 .
componentDidMount
1 .在第一次渲染后調(diào)用
2 .之后組件已經(jīng)生成了對(duì)應(yīng)的dom結(jié)構(gòu),可以通過(guò)this.getDomNode()來(lái)訪問(wèn)
3 .可以在這個(gè)方法中使用setTimeout或者ajax等異步操作
4 .
Mounting時(shí)涉及的函數(shù)
1 .constructor:加載的時(shí)候調(diào)用一次拾并,可以初始化state
2 .getDefaultProps:設(shè)置默認(rèn)的props,也可以使用defaultProps設(shè)置組件的默認(rèn)屬性
3 .getIniialState:初始化state,可以直接在constructor中定義this.state
4 .static getDerivedStateFromProps(props,state):組件每次render的時(shí)候咆爽,包括在組件創(chuàng)建之后脆丁,每次獲取新的props,state之后音榜,每次接收新的props之后都會(huì)返回一個(gè)對(duì)象作為新的state,返回null則說(shuō)明不需要更新state,配合componentDidUpdate蔚鸥,可以替代componentWillReceiveProps
5 .static getDerviedStateFromProps()
6 .render
7 .componentDidMount
8 .componentWillMount:這個(gè)生命周期函數(shù)即將過(guò)期惜论,新代碼中應(yīng)該避免使用他。
render()
1 .react最重要的步驟止喷,創(chuàng)建虛擬dom馆类,進(jìn)行diff算法,更新dom樹(shù)都在此進(jìn)行
2 .
componentWillReceiveProps
1 .組件接收到一個(gè)新的props弹谁,更新數(shù)據(jù)時(shí)調(diào)用乾巧,在初始render不會(huì)調(diào)用
2 .也就是只有父組件重新渲染,子組件接收到新的props才會(huì)觸發(fā)更新
shouldComponentUpdate
1 .返回一個(gè)布爾值预愤,在組件接收到新的props或者state調(diào)用沟于,在初始化或者forceUpdate時(shí)不被調(diào)用
2 .在確認(rèn)不更新組件時(shí)使用
3 .只對(duì)新舊props做了淺比較,沒(méi)有深比較,因?yàn)樗容^昂貴
function shallowEqual(obj, newObj) {
if (obj === newObj) {
return true;
}
const objKeys = Object.keys(obj);
const newObjKeys = Object.keys(newObj);
if (objKeys.length !== newObjKeys.length) {
return false;
}
// 關(guān)鍵代碼,只需關(guān)注 props 中每一個(gè)是否相等植康,無(wú)需深入判斷
return objKeys.every(key => {
return newObj[key] === obj[key];
});
}
componentWillUpdate
1 .返回一個(gè)布爾值旷太,在組件接收到新的props或者state,但是沒(méi)有render時(shí)調(diào)用,初始化不會(huì)被調(diào)用
2 .千萬(wàn)不要在這個(gè)函數(shù)中調(diào)用this.setState()方法.
componentDidUpdate
1 .組件完成更新之后調(diào)用供璧,初始化時(shí)不會(huì)被調(diào)用
getSnapshotBeforeUpdate(prevProps, prevState)
1 .update發(fā)生的時(shí)候存崖,每次獲取新的props或者state之后,都會(huì)返回一個(gè)新的對(duì)象作為state,返回null則說(shuō)明不會(huì)更新state
componentWillUnmount
1 .在組件從dom移除前輩調(diào)用
static getDerivedStateFromProps
1 .會(huì)在調(diào)用render方法之前調(diào)用睡毒,并且在初始掛載及其后續(xù)更新時(shí)每次都調(diào)用来惧,他返回一個(gè)新的state對(duì)象來(lái)更新state,如果返回null則不會(huì)更新任何內(nèi)容
2 .在state的值任何時(shí)候都取決于props.這個(gè)方法很實(shí)用
3 .但是這個(gè)方法會(huì)有一些bug,如果是以下幾種情況吕嘀,可以使用簡(jiǎn)單的替代方案
4 .不管什么原因违寞,每次render的時(shí)候都會(huì)執(zhí)行這個(gè)函數(shù)
getSnapshotBeforeUpdate
1 .在最近一次渲染輸出之前調(diào)用,還未掛載到dom節(jié)點(diǎn)之前
2 .他使得組件能在發(fā)生更改之前從DOM中捕獲一些信息偶房,比如滾動(dòng)位置趁曼,此生命周期的任何返回值都將作為參數(shù)傳遞給componentDidUpdate
1 .官方用法舉例
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// 我們是否在 list 中添加新的 items ?
// 捕獲滾動(dòng)位置以便我們稍后調(diào)整滾動(dòng)位置棕洋。
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// 如果我們 snapshot 有值挡闰,說(shuō)明我們剛剛添加了新的 items,
// 調(diào)整滾動(dòng)位置使得這些新 items 不會(huì)將舊的 items 推出視圖掰盘。
//(這里的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
錯(cuò)誤處理
1 .componentDidCatch(error,info)
1 .此生命周期在后代組件拋出錯(cuò)誤的時(shí)候被調(diào)用
2 .會(huì)在”提交“階段被調(diào)用摄悯,因此允許執(zhí)行副作用,應(yīng)該用于記錄一些錯(cuò)誤日志之類的情況
2 .static getDerivedStateFromError
1 .會(huì)在后代組件拋出錯(cuò)誤之后被調(diào)用愧捕,將拋出的錯(cuò)誤當(dāng)做參數(shù)奢驯,并返回一個(gè)新的值來(lái)更新state
2 .只會(huì)在渲染階段調(diào)用,因此不允許出現(xiàn)副作用次绘。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染可以顯降級(jí) UI
return { hasError: true };
}
render() {
if (this.state.hasError) {
// 你可以渲染任何自定義的降級(jí) UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
forceUpdate
1 .默認(rèn)情況下瘪阁,當(dāng)組件的state,props發(fā)生變化時(shí),組件將會(huì)重新渲染邮偎。如果render方法依賴于其他數(shù)據(jù)管跺,或者說(shuō)想要頁(yè)面立馬渲染,可以調(diào)用forceUpdate強(qiáng)制讓組件重新渲染
2 .調(diào)用forceUpdate會(huì)強(qiáng)制組件調(diào)用render方法禾进,此時(shí)組件會(huì)跳過(guò)該組件的shouldComponentUpdate豁跑,但是子組件會(huì)觸發(fā)正常的生命周期方法
3 .總的來(lái)說(shuō)應(yīng)該避免使用forceUpdate,盡量在render中使用this.props,this.state來(lái)觸發(fā)框架更新
備注
1 .17的時(shí)候會(huì)刪掉WillMount,ReceiveProps,WillUpdate
2 .官網(wǎng)不使用ES6的部分有介紹到這里的東西
1 .聲明默認(rèn)的props
var Greeting = createReactClass({
getDefaultProps: function() {
return {
name: 'Mary'
};
},
})
2 .初始化state
getInitialState: function() {
return {count: this.props.initialCount};
},
class Hello extends React.Component {
render() {
return React.createElement('div', null, `Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}, null),
document.getElementById('root')
);
注意
1 .willMount和willUpdate會(huì)被多次執(zhí)行泻云,so艇拍,不要放有副作用的處理。
掛載的時(shí)候
1 .constructor
2 .static getDerivedStateFromProps
3 .render
4 .componentDidMount
更新的時(shí)候:當(dāng)props或state發(fā)生變化的時(shí)候會(huì)觸發(fā)更新
1 .static getDerivedStateFormProps
2 .shouldComponentUpdate
3 .render
4 .getSnapshotBeforeUpdate
5 .componentDidUpdate
6 .componentWillUpdate,componentWillReceiveProps.這倆即將過(guò)期宠纯,不要使用
卸載的時(shí)候
setState的時(shí)間
1 .