react生命周期的基本用法

寫react也快半年了布隔,講一下自己對于生命周期的理解及各個生命周期的作用

首先,看一下一個組件的構(gòu)造

import React,{ Component } from 'react';

class Demo extends Component {
  constructor(props,context) {
      super(props,context)
      this.state = {
          //定義state
      }
  }
componentWillMount () {
}
componentDidMount () {
}
componentWillReceiveProps (nextProps) {
}
shouldComponentUpdate (nextProps,nextState) {
}
componentWillUpdate (nextProps,nextState) {
}
componentDidUpdate (prevProps,prevState) {
}
render () {
    return (
        <div></div>
    )
}
componentWillUnmount () {
}
}
export default Demo;

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

下面我從constructor構(gòu)造函數(shù)開始,從參數(shù)铛嘱,作用暖释,用法各方面總結(jié)

1、constructor

constructor參數(shù)接受兩個參數(shù)props,context
可以獲取到父組件傳下來的的props,context,如果你想在constructor構(gòu)造函數(shù)內(nèi)部(注意是內(nèi)部哦墨吓,在組件其他地方是可以直接接收的)使用props或context,則需要傳入球匕,并傳入super對象。

 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帖烘,那么只傳入一個參數(shù)即可亮曹,如果都不可以,就都不傳。

關(guān)于ES6的class constructor和super

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

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

2、componentWillMount 組件將要掛載

1历极、組件剛經(jīng)歷constructor,初始完數(shù)據(jù)
2窄瘟、組件還未進入render,組件還未渲染完成趟卸,dom還未渲染

componentWillMount 一般用的比較少蹄葱,更多的是用在服務(wù)端渲染,(我還未使用過react服務(wù)端渲染哈锄列,所以也寫不了很多)
但是這里有一個問題

ajax請求能寫在willmount里嗎图云?
:答案是不推薦,別這么寫

1.雖然有些情況下并不會出錯邻邮,但是如果ajax請求過來的數(shù)據(jù)是空竣况,那么會影響頁面的渲染,可能看到的就是空白筒严。
2.不利于服務(wù)端渲染丹泉,在同構(gòu)的情況下,生命周期會到componentwillmount鸭蛙,這樣使用ajax就會出錯

3摹恨、componentDidMount 組件渲染完成

組件第一次渲染完成,此時dom節(jié)點已經(jīng)生成娶视,可以在這里調(diào)用ajax請求晒哄,返回數(shù)據(jù)setState后組件會重新渲染

4.componentWillReceiveProps (nextProps)

componentWillReceiveProps在接受父組件改變后的props需要重新渲染組件時用到的比較多
它接受一個參數(shù)

1.nextProps
通過對比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的第二個參數(shù)(回調(diào))可以打印出新的state
  })
}
關(guān)于setState的用法及深入了解 后面會專門整理一篇文章

5.shouldComponentUpdate(nextProps,nextState)

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

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

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

6.componentWillUpdate (nextProps,nextState)

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

7.render函數(shù)

render函數(shù)會插入jsx生成的dom結(jié)構(gòu)耍目,react會生成一份虛擬dom樹,在每一次組件更新時徐绑,在此react會通過其diff算法比較更新前后的新舊DOM樹邪驮,比較以后,找到最小的有差異的DOM節(jié)點傲茄,并重新渲染

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

意思你現(xiàn)在可以這樣:

render () {
  return " "

}
或者這樣:

render () {
  return [
                <div></div>
             <div></div>

]
}

8草巡、componentDidUpdate(prevProps,prevState)

組件更新完畢后守呜,react只會在第一次初始化成功會進入componentDidmount,之后每次重新渲染后都會進入這個生命周期,這里可以拿到prevProps和prevState山憨,即更新前的props和state弛饭。
如果你理解了組件一次重新渲染的過程,那么你應(yīng)該理解下面5處打印出來的state應(yīng)該是相同的萍歉。(關(guān)于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) //4
    return (
        <div></div>
    )
}

9、componentWillUnmount ()

componentWillUnmount也是會經(jīng)常用到的一個生命周期枪孩,初學(xué)者可能用到的比較少憔晒,但是用好這個確實很重要的哦

1.clear你在組建中所有的setTimeout,setInterval
2.移除所有組建中的監(jiān)聽 removeEventListener
3.也許你會經(jīng)常遇到這個warning:

Can only update a mounted or mounting component. This usually means you called setState() on an       
 unmounted component. This is a no-op. Please check the code for the undefined component.

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

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

拓展:

1.react生命周期父子組件渲染順序
父子組件拒担, componentWillMount生命周期是先進入父組件還是子組件?
componentDidMount呢攻询?
答案參考我的另一篇文章http://www.reibang.com/p/ee122bb5b14b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末从撼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子钧栖,更是在濱河造成了極大的恐慌低零,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拯杠,死亡現(xiàn)場離奇詭異掏婶,居然都是意外死亡,警方通過查閱死者的電腦和手機潭陪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門雄妥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來最蕾,“玉大人,你說我怎么就攤上這事老厌∥猎颍” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵枝秤,是天一觀的道長壹粟。 經(jīng)常有香客問我,道長宿百,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任洪添,我火速辦了婚禮垦页,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘干奢。我一直安慰自己痊焊,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布忿峻。 她就那樣靜靜地躺著薄啥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逛尚。 梳的紋絲不亂的頭發(fā)上垄惧,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機與錄音绰寞,去河邊找鬼到逊。 笑死,一個胖子當(dāng)著我的面吹牛滤钱,可吹牛的內(nèi)容都是我干的觉壶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼件缸,長吁一口氣:“原來是場噩夢啊……” “哼铜靶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起他炊,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤争剿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后痊末,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秒梅,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年舌胶,在試婚紗的時候發(fā)現(xiàn)自己被綠了捆蜀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辆它,靈堂內(nèi)的尸體忽然破棺而出誊薄,到底是詐尸還是另有隱情,我是刑警寧澤锰茉,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布呢蔫,位于F島的核電站,受9級特大地震影響飒筑,放射性物質(zhì)發(fā)生泄漏片吊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一协屡、第九天 我趴在偏房一處隱蔽的房頂上張望俏脊。 院中可真熱鬧,春花似錦肤晓、人聲如沸爷贫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漫萄。三九已至,卻和暖如春盈匾,著一層夾襖步出監(jiān)牢的瞬間腾务,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工削饵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留窑睁,地道東北人。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓葵孤,卻偏偏與公主長得像担钮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子尤仍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容