新手對React生命週期的理解

我就是個小前端發表於2019-05-10

React生命週期圖解

  1. 先上圖(引用官網圖片)

React生命週期講解

  1. 其實總結就是 進入當前頁面,,然後渲染頁面,載入資料,渲染demo,資料更新,元件解除安裝

  2. constructor

/*
* constructor 其實是Es6 裡面帶的一個屬性,代表初始化,但是元件未掛載
* constructor的固定寫法如下
* 比如你react 需要定義一些 
* State 的值就可以定義在 constructor裡面,這個是一個很好的習慣
*/
import React, { Component } from 'react';
 class APP extends Component {

  constructor(props) {
    super(props);
    this.state = {
    counter: 0,
  }
  }
  render() {
    return (
      <div>
        Hello word
    </div>
    )
  }
}

export default APP;

複製程式碼

4 componentWillMount

/*
* 元件初始化時只呼叫,
* 以後元件更新不呼叫,
* 整個生命週期只呼叫一次,此時可以修改state
*/

import React, { Component } from 'react';

class APP extends Component {
  constructor(props) {
    super(props);
    this.state = {
    date: new Date()
    }
  }
  /*
  * 這個就是元件初始化建立的時候才會執行的方法
  * 並且只會執行一次,此時可以去修改 State裡面的值
  * 我這裡借用官網的定時器的例子,
  * 如果看不懂es6 的程式碼,很簡單,把他還原成es5
  * https://www.babeljs.cn/repl  把es6的程式碼複製進去就變成es5的程式碼了
  */
  componentWillMount(){
   this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  /*你執行的方法函式可以寫在這裡,也可以寫在底部,但是一般我都寫上面
  * 美觀,並且方便人檢視,我有一個習慣,寫函式方法我都會寫一個註釋,可能
  * 有人說,會增加安裝包大小,其實也不多那幾K,可以寫註釋方便別人檢視,自己以後
  * 也能看得懂,取名,要適合當前場景,別TM去取拼音
  */
  /*
  * 定時器
  */
  tick() {
    this.setState({
      date: new Date()
    });
   }
  
  render() {
    return (
      <div>
         <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
    </div>
    )
  }

}
export default APP;
複製程式碼

5 render

/*
* react最重要的步驟,
* 建立虛擬dom,
* 進行diff演算法,當你元件傳遞資料更新變化都會執行 render
* 更新dom樹都在此進行。此時就不能更改state了
* 你這裡再去更改state 就會報錯哦,記住了 !!!
* 一般父元件傳遞的props 都會在此獲取
* 父子之間傳遞資料,可以參考我另一篇文章
* https://blog.csdn.net/wonaixiaoshenshen/article/details/89221569
*/
import React, { Component } from 'react';
class APP extends Component {
  render() {
  const { moneylist} =this.props
  console.log(`這裡可以列印一下moneylist的值,每次都會更新`${moneylist})
    return (
      <div>
        Hello word
    </div>
    )
  }
}
export default APP;

複製程式碼

6 componentDidMount

/*
* 這個屬性就 厲害啦,這個屬性就是載入請求資料的最好放處,
* 此處是axios 的方式,feach 的方式其實同理
*/
import React, { Component } from 'react';
import axios from 'axios';
class APP extends Component {
  constructor(props) {
    super(props);
    this.state = {
    List: [],
    }
componentDidMount(){
   /*
  *先存一下this,以防使用箭頭函式this會亂指,此處可以優化哈。
  */
    const _this=this;  
    axios.get(`你請求的後端的地址`)
    .then(function (response) {
      _this.setState({
        List:response.data,
      });
    })
    .catch(function (error) {
      console.log(error);
    })
}
  render() {
    return (
    /*
    * 如果要迴圈資料的話就在這裡寫一個map 迴圈就好了
    */
      <div>
        Hello word
    </div>
    )
  }
}
export default APP;

複製程式碼

7 componentWillReceiveProps(nextProps)

import React, { Component } from 'react';
class APP extends Component {

componentWillReceiveProps(nextProps){
/*  此生命週期是需要條件成立才會執行的
*   元件初始化時不呼叫
*   元件接受新的props時呼叫。
*   常用於父子元件傳值,子元件寫這個方法函式
/
}
  render() {
    return (
      <div>
        Hello word
    </div>
    )
  }
}
export default APP;
複製程式碼

8 shouldComponentUpdate(nextProps, nextState)

/*
* 當沒有導致state的值發生變化的setState是否會導致當前頁面重渲染 
* 所以,shouldComponentUpdate會阻止不必要的沒有意義的重渲染
* shouldComponentUpdate函式是重渲染時render()
* 函式呼叫前被呼叫的函式,它接受兩個引數:nextProps和nextState,
* 分別表示下一個props和下一個state的值。
* 當函式返回false時候,阻止接下來的render()函式的呼叫,
* 阻止元件重渲染,而返回true時,元件照常重渲染。
*
*/

import React, { Component } from 'react';
class Son extends Component{
  render(){
    const {index,number,handleClick} = this.props
    /*
    * 在每次渲染子元件時,列印該子元件的數字內容
    */
    console.log(number);
    return <h1 onClick ={() => handleClick(index)}>{number}</h1>
  }
}
class Father extends Component{
  constructor(props) {
    super(props);
    this.state = {
      numberArray:[0,1,2]
    }
  }
  /*
  *點選後使numberArray中陣列下標為index的數字值加一,重渲染對應的Son元件
  */
  handleClick = (index) => {
     let preNumberArray = this.state.numberArray
     preNumberArray[index] += 1;
     this.setState({
        numberArray:preNumberArray
     })
  }
  render(){
    return(
             <div style ={{margin:30}}>{
              this.state.numberArray.map(
                (number,key) => {
                 return (
                           <Son
                           key = {key}
                           index = {key}
                           number ={number}
                           handleClick ={this.handleClick}/>
                 ) 
                }
                )
              }
           </div>)
  }
}
export default Father
/*
* 但是這樣會導致你的頁面效能下降,這個例子是我一開始
* 在學的時候,看到有位大佬寫過這個我就記錄下來了,然後這樣雖然是可以實現效果
* 但是了,會導致沒有必要的渲染,如何解決了?
* 就是在子元件中渲染之前去進行判斷,是否資料變化了,如果沒有變化,則停止,沒有
* 必要再進行渲染
*/
複製程式碼

解決方案如下

import React, { Component } from 'react';
class Son extends Component{
/*
* 子元件中,一開始進行判斷,當前傳遞的props 是否相同
* 如果相同,則暫停渲染(指渲染一次),否則就渲染
*/
  shouldComponentUpdate(nextProps,nextState){
      if(nextProps.number == this.props.number){
        return false
      }
      return true
  }
  render(){
    const {index,number,handleClick} = this.props
    console.log(number);
    return <h1 onClick ={() => handleClick(index)}>{number}</h1>
  }
}
class Father extends Component{
  constructor(props) {
    super(props);
    this.state = {
      numberArray:[0,1,2]
    }
  }
  handleClick = (index) => {
     let preNumberArray = this.state.numberArray
     preNumberArray[index] += 1;
     this.setState({
        numberArray:preNumberArray
     })
  }
  render(){
    return(<div style ={{margin:30}}>{
              this.state.numberArray.map(
                (number,key) => {
                 return <Son
                           key = {key}
                           index = {key}
                           number ={number}
                           handleClick ={this.handleClick}/>
                }
                )
              }
           </div>)
  }
}
export default Father
複製程式碼

9 .componentWillUnmount

import React, { Component } from 'react';

class APP extends Component {

componentWillUnmount(){
/*
* 元件將要解除安裝時呼叫,
* 一些事件監聽和定時器需要在此時清除
*/
}
  render() {
    return (
      <div>
        Hello word
    </div>
    )
  }
}
export default APP;

複製程式碼
  • 本人最近在學習react,特總結一份自己的理解,發表文章, 只是想能給你一點點啟發 (僅適合小白觀看,大佬出門右轉 ,開玩笑啦,我還是很希望大佬指點一下的,謝謝 ^-^) 也給我自己一個筆記的地方,好記性不如爛筆頭說的就是這個道理吧 !!!

相關文章