首先阵难,看一下一個(gè)組件的構(gòu)造
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;當(dāng)然前段時(shí)間react16發(fā)布還新加了處理錯(cuò)誤信息的生命周期 componentDidCatch(打個(gè)標(biāo)記 還未使用過英上,下次深入研究)
下面我從constructor構(gòu)造函數(shù)開始胧瓜,從參數(shù),作用跺株,用法各方面總結(jié)
1复濒、constructor
constructor參數(shù)接受兩個(gè)參數(shù)props,context
可以獲取到父組件傳下來的的props,context,如果你想在constructor構(gòu)造函數(shù)內(nèi)部(注意是內(nèi)部哦,在組件其他地方是可以直接接收的)使用props或context,則需要傳入乒省,并傳入super對(duì)象巧颈。
constructor(props,context) {super(props,context)console.log(this.props,this.context)// 在內(nèi)部可以使用props和context}
當(dāng)然如果你只需要在構(gòu)造函數(shù)內(nèi)使用props或者context,那么只傳入一個(gè)參數(shù)即可袖扛,如果都不可以砸泛,就都不傳。
關(guān)于ES6的class constructor和super
只要組件存在constructor,就必要要寫super,否則this指向會(huì)錯(cuò)誤
constructor() {console.log(this)// 報(bào)錯(cuò)蛆封,this指向錯(cuò)誤}
2唇礁、componentWillMount 組件將要掛載
1、組件剛經(jīng)歷constructor,初始完數(shù)據(jù)
2惨篱、組件還未進(jìn)入render盏筐,組件還未渲染完成,dom還未渲染
componentWillMount 一般用的比較少砸讳,更多的是用在服務(wù)端渲染琢融,(我還未使用過react服務(wù)端渲染哈界牡,所以也寫不了很多)
但是這里有一個(gè)問題
ajax請(qǐng)求能寫在willmount里嗎?
:答案是不推薦漾抬,別這么寫
1.雖然有些情況下并不會(huì)出錯(cuò)宿亡,但是如果ajax請(qǐng)求過來的數(shù)據(jù)是空,那么會(huì)影響頁面的渲染奋蔚,可能看到的就是空白她混。
2.不利于服務(wù)端渲染,在同構(gòu)的情況下泊碑,生命周期會(huì)到componentwillmount,這樣使用ajax就會(huì)出錯(cuò)
3毯欣、componentDidMount 組件渲染完成
組件第一次渲染完成馒过,此時(shí)dom節(jié)點(diǎn)已經(jīng)生成,可以在這里調(diào)用ajax請(qǐng)求酗钞,返回?cái)?shù)據(jù)setState后組件會(huì)重新渲染
4.componentWillReceiveProps (nextProps)
componentWillReceiveProps在接受父組件改變后的props需要重新渲染組件時(shí)用到的比較多
它接受一個(gè)參數(shù)
1.nextProps
通過對(duì)比nextProps和this.props腹忽,將nextProps setState為當(dāng)前組件的state,從而重新渲染組件
componentWillReceiveProps (nextProps) {? ? nextProps.openNotice !==this.props.openNotice &&this.setState({? ? ? ? openNotice:nextProps.openNotice? ? }砚作,() => {? ? ? console.log(this.state.openNotice:nextProps)//將state更新為nextProps,在setState的第二個(gè)參數(shù)(回調(diào))可以打印出新的state})}
關(guān)于setState的用法及深入了解 后面會(huì)專門整理一篇文章
5.shouldComponentUpdate(nextProps,nextState)
唯一用于控制組件重新渲染的生命周期窘奏,由于在react中,setState以后葫录,state發(fā)生變化着裹,組件會(huì)進(jìn)入重新渲染的流程,(暫時(shí)這么理解米同,其實(shí)setState以后有些情況并不會(huì)重新渲染骇扇,比如數(shù)組引用不變)在這里return false可以阻止組件的更新
因?yàn)閞eact父組件的重新渲染會(huì)導(dǎo)致其所有子組件的重新渲染,這個(gè)時(shí)候其實(shí)我們是不需要所有子組件都跟著重新渲染的面粮,因此需要在子組件的該生命周期中做判斷
對(duì)于react初學(xué)者少孝,可能涉及這個(gè)生命周期的機(jī)會(huì)比較少,但是如果你的項(xiàng)目開始注重性能優(yōu)化熬苍,隨著你對(duì)react的喜愛和深入稍走,你就會(huì)用到這個(gè)生命周期
6.componentWillUpdate (nextProps,nextState)
shouldComponentUpdate返回true以后,組件進(jìn)入重新渲染的流程柴底,進(jìn)入componentWillUpdate,這里同樣可以拿到nextProps和nextState
7.render函數(shù)
render函數(shù)會(huì)插入jsx生成的dom結(jié)構(gòu)婿脸,react會(huì)生成一份虛擬dom樹,在每一次組件更新時(shí)似枕,在此react會(huì)通過其diff算法比較更新前后的新舊DOM樹盖淡,比較以后,找到最小的有差異的DOM節(jié)點(diǎn)凿歼,并重新渲染
react16中 render函數(shù)允許返回一個(gè)數(shù)組褪迟,單個(gè)字符串等冗恨,不在只限制為一個(gè)頂級(jí)DOM節(jié)點(diǎn),可以減少很多不必要的div(當(dāng)然注意升級(jí)你的react版本味赃,將現(xiàn)有項(xiàng)目升到react16并不會(huì)出現(xiàn)什么bug掀抹,唯一注意的是proTypes類型檢測(cè)換了名字~)
意思你現(xiàn)在可以這樣:
render() {return" "
}
或者這樣:
render () {return[
]
}
8、componentDidUpdate(prevProps,prevState)
組件更新完畢后心俗,react只會(huì)在第一次初始化成功會(huì)進(jìn)入componentDidmount,之后每次重新渲染后都會(huì)進(jìn)入這個(gè)生命周期傲武,這里可以拿到prevProps和prevState,即更新前的props和state城榛。
如果你理解了組件一次重新渲染的過程揪利,那么你應(yīng)該理解下面5處打印出來的state應(yīng)該是相同的。(關(guān)于setState異步是同步的理解狠持,后面也會(huì)整理一篇文章~)
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也是會(huì)經(jīng)常用到的一個(gè)生命周期,初學(xué)者可能用到的比較少喘垂,但是用好這個(gè)確實(shí)很重要的哦
1.clear你在組建中所有的setTimeout,setInterval
2.移除所有組建中的監(jiān)聽 removeEventListener
3.也許你會(huì)經(jīng)常遇到這個(gè)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.
是因?yàn)槟阍诮M建中的ajax請(qǐng)求返回中setState,而你組件銷毀的時(shí)候甜刻,請(qǐng)求還未完成,因此會(huì)報(bào)warning
解決辦法為
componentDidMount() {this.isMount ===trueaxios.post().then((res) =>{this.isMount &&this.setState({// 增加條件ismount為true時(shí)aaa:res? ? })})}componentWillUnmount() {this.isMount ===false}
作者:Evan_zhan
鏈接:http://www.reibang.com/p/c9bc994933d5
來源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有正勒,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處得院。