【React】: React的生命週期

概述

生命週期的每個階段總是伴隨着一些方法的調用,這些方法就是生命週期的鉤子函數
鉤子函數的作用:爲開發人員在不同操作階段提供了十幾
只有 類組件 纔有生命週期
 
生命週期的圖片:

 同時有:

1.1 創建時 的生命週期執行順序

 編寫以下代碼,從而驗證constructor,render,componentDidMount的順序:

class App5 extends React.Component
{
  constructor(props)
  {
    super(props)

    console.warn("生命週期鉤子函數:constructor")
  }

  componentDidMount()
  {
    console.warn("生命週期鉤子函數:componentDidMount")
  }

  render()
{
  console.warn("生命週期鉤子函數:render")
  return (
<div>
<h3></h3>
<h1>統計豆豆被打的次數:</h1>
<button id='btn'>打豆豆</button>
</div>

  )
}
}

ReactDOM.render(<App5/>,document.getElementById('root9'))

在開發者工具中發現執行順序爲:

當然我們對這三個狀態還有以下總結:

 

備註:不能在render裏調用setstate的原因是:在render裏既能夠更新狀態,也會更新ui,具體可以參考前面的生命週期圖,render裏調用setstate,而setstate也會繼續調用render,這樣就會導致遞歸調用,從而導致error。

一定要在render裏進行調用setstate,我們可以採用箭頭函數,同時可以將this從render當中抽離出來,這樣相當於在生命週期的“更新時”再繼續更新Ui,代碼如下:

class AppThree extends React.Component
{

  state={
    count:0
  }

  //組件當中的state,可以通過this.state來進行調用
  //使用setState,來修改數據,直接使用this.state.count+1,來修改是行不通的
  //備註:如果直接使用事件抽離的方法,把render函數當中的邏輯抽離出來,但是在當前class的其他
  //的函數當中,是無法調用到this的。 因此在其他函數中無法調用this.setState是肯定的。

  render(){
    return (
      <div>
        <h1>計數器</h1>

        <button onClick={() => {
          this.setState({
            count:this.state.count+1
          })

        } }>
        +1</button>
        <div>這是一個有狀態組件當中的數據count。{this.state.count}</div>
      </div>
    )
  }
 
}

這樣就可以保證這裏的this不是指的render裏的this,而是render外部的this。當然還可以將這個this.setstate的邏輯進行抽離出來:

class AppSix extends React.Component
{


  state={
    count:0
  }

  onIncrement = () => 
  {
    this.setState({
      count:this.state.count+1
    })
  }

  render(){
    return (
      <div>
        <h1>計數器</h1>
        {/*在react當中,onclick方法都需要用花括號括起來,再來表示其中的方法,這裏的箭頭函數可以直接實現調用,只是沒有對這個箭頭函數
        進行命名,也就是令 hello = () => this.onIncrement(),是否命名都一樣的
        */}
        <button onClick={this.onIncrement}>+1</button>
    )
  }
 
}


ReactDOM.render(<AppSix />, document.getElementById('event_six'))

對於componentDidMount,我們可以在裏面進行網絡請求和dom操作,因爲它是等渲染完成後,纔開始進行這個生命進程。

1.2 更新時的生命週期

在更新時,也就是值的初始的渲染都完成了,在渲染完成後,用戶如果點擊了界面,網頁如何使用鉤子函數對不同狀態下的網頁進行檢測和更新。有三種情況都會導致組件進行重新渲染,分別是調用:

  1. New props(新參數被調用)
  2. setState() 
  3. forceUpdate() : 也就是強制更新
class App6 extends React.Component{

constructor(props)
{
  super(props)

  this.state={
    count:0
  }
}

handleClick= () =>
{
  this.setState({
    count:this.state.count+1
  })
}


render()
{
  return (
    <div>
      <h3>5.2 更新時的生命週期</h3>
      <Counter2 count={this.state.count }/>
      <button onClick={this.handleClick}>打豆豆</button>
    </div>

  )

}

}

class Counter2 extends React.Component
{
  render()
  {
    return <h3>統計豆豆被打的次數:{this.props.count}</h3>
  }


}


ReactDOM.render(<App6/>,document.getElementById('root10'))

 這裏用到了子組件counter2,並且子組件接受到了參數props,因此在接受到了參數props後,確實會對ui進行更新,也就是進行重新渲染,我們點擊一次按鈕,子組件都會接受到一次參數,這樣打豆豆的次數就會發生變化。

我們可以看到ComponentDidUpdate()是在render函數之後,纔開始執行的,因此有以下的的圖片:

 

 

1.3 卸載時的生命週期

 我們在打完豆豆超過3次後,子組件消失,因此可以使用compomentWillUnmount函數,執行清理工作。代碼如下:

class App6 extends React.Component{

constructor(props)
{
  super(props)

  this.state={
    count:0
  }
}

handleClick= () =>
{
  this.setState({
    count:this.state.count+1
  })
}


render()
{
  return (
    <div>
      <h3>5.2 更新時的生命週期</h3>
        {
          this.state.count > 3 ? (
            <p>豆豆被打死了</p>

          ) :(
            <Counter2 count={this.state.count }/>
          )

        }

     
      <button onClick={this.handleClick}>打豆豆</button>
    </div>

  )

}

}

class Counter2 extends React.Component
{
  render()
  {
    console.warn("子組件--更新時--render函數被渲染")
    return <h3>統計豆豆被打的次數:{this.props.count}</h3>
  }

  componentDidUpdate()
  {
    console.warn("子組件--更新時--componentDidUpdate函數被渲染")
    
  }

  componentWillUnmount()
  {
    //我們在父組件當中規定了這個子組件在超過3次之後銷燬,因此銷燬後應該調用這個函數
    console.warn("子組件--生命週期鉤子函數: componentWillUnmount")
  }


}


ReactDOM.render(<App6/>,document.getElementById('root10'))

 

 我們在發現子組件消失後,確實compomentWillUnmount函數被執行了,warning被打印出。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章