七、簡單了解react的生命周期

首先,看一下一個組件的構造

importReact,{ Component }from'react';classDemoextendsComponent{constructor(props,context) {super(props,context)this.state = {//定義state}? }componentWillMount () {}componentDidMount () {}componentWillReceiveProps (nextProps) {}shouldComponentUpdate (nextProps,nextState) {}componentWillUpdate (nextProps,nextState) {}componentDidUpdate (prevProps,prevState) {}render () {return(

)}componentWillUnmount () {}}exportdefaultDemo;

當然前段時間react16發布還新加了處理錯誤信息的生命周期 componentDidCatch(打個標記 還未使用過,下次深入研究)

下面我從constructor構造函數開始,從參數,作用,用法各方面總結

1、constructor

constructor參數接受兩個參數props,context

可以獲取到父組件傳下來的的props,context,如果你想在constructor構造函數內部(注意是內部哦,在組件其他地方是可以直接接收的)使用props或context,則需要傳入,并傳入super對象。

constructor(props,context) {super(props,context)console.log(this.props,this.context)// 在內部可以使用props和context}

當然如果你只需要在構造函數內使用props或者context,那么只傳入一個參數即可,如果都不可以,就都不傳。

關于ES6的class constructor和super

只要組件存在constructor,就必要要寫super,否則this指向會錯誤

constructor() {console.log(this)// 報錯,this指向錯誤}

2、componentWillMount 組件將要掛載

1、組件剛經歷constructor,初始完數據

2、組件還未進入render,組件還未渲染完成,dom還未渲染

componentWillMount 一般用的比較少,更多的是用在服務端渲染,(我還未使用過react服務端渲染哈,所以也寫不了很多)

但是這里有一個問題

ajax請求能寫在willmount里嗎?

:答案是不推薦,別這么寫

1.雖然有些情況下并不會出錯,但是如果ajax請求過來的數據是空,那么會影響頁面的渲染,可能看到的就是空白。

2.不利于服務端渲染,在同構的情況下,生命周期會到componentwillmount,這樣使用ajax就會出錯

3、componentDidMount 組件渲染完成

組件第一次渲染完成,此時dom節點已經生成,可以在這里調用ajax請求,返回數據setState后組件會重新渲染

4.componentWillReceiveProps (nextProps)

componentWillReceiveProps在接受父組件改變后的props需要重新渲染組件時用到的比較多

它接受一個參數

1.nextProps

通過對比nextProps和this.props,將nextProps setState為當前組件的state,從而重新渲染組件

componentWillReceiveProps (nextProps) {? ? nextProps.openNotice !==this.props.openNotice &&this.setState({? ? ? ? openNotice:nextProps.openNotice? ? },() => {? ? ? console.log(this.state.openNotice:nextProps)//將state更新為nextProps,在setState的第二個參數(回調)可以打印出新的state})}

關于setState的用法及深入了解 后面會專門整理一篇文章

5.shouldComponentUpdate(nextProps,nextState)

唯一用于控制組件重新渲染的生命周期,由于在react中,setState以后,state發生變化,組件會進入重新渲染的流程,(暫時這么理解,其實setState以后有些情況并不會重新渲染,比如數組引用不變)在這里return false可以阻止組件的更新

因為react父組件的重新渲染會導致其所有子組件的重新渲染,這個時候其實我們是不需要所有子組件都跟著重新渲染的,因此需要在子組件的該生命周期中做判斷

對于react初學者,可能涉及這個生命周期的機會比較少,但是如果你的項目開始注重性能優化,隨著你對react的喜愛和深入,你就會用到這個生命周期

6.componentWillUpdate (nextProps,nextState)

shouldComponentUpdate返回true以后,組件進入重新渲染的流程,進入componentWillUpdate,這里同樣可以拿到nextProps和nextState

7.render函數

render函數會插入jsx生成的dom結構,react會生成一份虛擬dom樹,在每一次組件更新時,在此react會通過其diff算法比較更新前后的新舊DOM樹,比較以后,找到最小的有差異的DOM節點,并重新渲染

react16中 render函數允許返回一個數組,單個字符串等,不在只限制為一個頂級DOM節點,可以減少很多不必要的div(當然注意升級你的react版本,將現有項目升到react16并不會出現什么bug,唯一注意的是proTypes類型檢測換了名字~)

意思你現在可以這樣:

render() {return" "

}

或者這樣:

render () {return[

]

}

8、componentDidUpdate(prevProps,prevState)

組件更新完畢后,react只會在第一次初始化成功會進入componentDidmount,之后每次重新渲染后都會進入這個生命周期,這里可以拿到prevProps和prevState,即更新前的props和state。

如果你理解了組件一次重新渲染的過程,那么你應該理解下面5處打印出來的state應該是相同的。(關于setState異步是同步的理解,后面也會整理一篇文章~)

componentWillReceiveProps (nextProps,nextState) {this.setState({fengfeng:nextProps.fengfeng? ? },()=>{console.log(this.state.fengfeng)//1})? ? }shouldComponentUpdate (nextProps,nextState) {console.log(nextState.fengfeng)//2}componentWillUpdate (nextProps,nextState) {console.log(nextState.fengfeng)//3}componentDidUpdate (prevProps,prevState) {console.log(this.state.fengfeng)//5}render () {console.log(this.state.fengfeng)//4return(

)}

9、componentWillUnmount ()

componentWillUnmount也是會經常用到的一個生命周期,初學者可能用到的比較少,但是用好這個確實很重要的哦

1.clear你在組建中所有的setTimeout,setInterval

2.移除所有組建中的監聽 removeEventListener

3.也許你會經常遇到這個warning:

Can only update a mountedormounting component. This usually means you called setState() on an? ? ? ? unmounted component. Thisisa no-op. Please check the codeforthe undefined component.

是因為你在組建中的ajax請求返回中setState,而你組件銷毀的時候,請求還未完成,因此會報warning

解決辦法為

componentDidMount() {this.isMount ===trueaxios.post().then((res) =>{this.isMount &&this.setState({// 增加條件ismount為true時aaa:res? ? })})}componentWillUnmount() {this.isMount ===false}

作者:Evan_zhan

鏈接:http://www.lxweimin.com/p/c9bc994933d5

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容