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(打個標(biāo)記 還未使用過,下次深入研究)

下面我從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、組件還未進(jìn)入render,組件還未渲染完成,dom還未渲染

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

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

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

3、componentDidMount 組件渲染完成

組件第一次渲染完成,此時dom節(jié)點(diǎn)已經(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ā)生變化,組件會進(jìn)入重新渲染的流程,(暫時這么理解,其實(shí)setState以后有些情況并不會重新渲染,比如數(shù)組引用不變)在這里return false可以阻止組件的更新

因?yàn)閞eact父組件的重新渲染會導(dǎo)致其所有子組件的重新渲染,這個時候其實(shí)我們是不需要所有子組件都跟著重新渲染的,因此需要在子組件的該生命周期中做判斷

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

6.componentWillUpdate (nextProps,nextState)

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

7.render函數(shù)

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

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

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

render () {
  return " "

}
或者這樣:

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

]
}

8、componentDidUpdate(prevProps,prevState)

組件更新完畢后,react只會在第一次初始化成功會進(jìn)入componentDidmount,之后每次重新渲染后都會進(jìn)入這個生命周期,這里可以拿到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é)者可能用到的比較少,但是用好這個確實(shí)很重要的哦

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.

是因?yàn)槟阍诮M建中的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生命周期是先進(jìn)入父組件還是子組件?
componentDidMount呢?
答案參考我的另一篇文章http://www.itdecent.cn/p/ee122bb5b14b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容