首先,看一下一個組件的構造
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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。