1. 程式人生 > >【React】使用shouldComponentUpdate對元件效能進行優化

【React】使用shouldComponentUpdate對元件效能進行優化

前言

react中,我們通過this.setState()方法去改變自身元件的state,以及子元件的props,然後觸發元件重新渲染。
那麼,當我們setState之後,新的state和舊的state值是一樣,頁面也會進行重新渲染,這是不必要的,也是損耗效能的。

舉例

寫一個demo

import React, { Component } from 'react';

//子元件
const Son = (props) => {
  console.log("--son--render----")
  return <div> Son:
{props.son}</div> } //父元件,傳給子元件一個on的prop class App extends Component { state = { name: 'scarlet', son: 2 } componentDidMount() { setInterval(() => { this.setState({ name: this.state.name, son: this.state.son }) }, 1 * 1000) } render() { console.
log("--parent--render----") return ( <div className="App"> <h2>name : {this.state.name}</h2> <Son son={this.state.son}></Son> </div> ); } } export default App;

程式碼中有:

  state = {
    name: 'scarlet',
    son: 2
  }

其中,name是父元件自己渲染,son是傳給子元件渲染。
以上例子中,我們用一個setInterval每隔1s去setState,可以看到以下列印:
在這裡插入圖片描述


從抓的列印中,可以知道,即使我們設定了state,前後的state中的值是一樣的,但是在子元件和父元件中,都會觸發render。這些操作都是冗餘的,沒有必要的。

優化

此時鉤子函式:shouldComponentUpdate非常關鍵。
這個函式是re-render是render()函式呼叫前被呼叫的,他的兩個引數nextProps和nextState,分別表示下一個props和下一個state的值。我們重寫這個鉤子,當函式返回false時,阻止接下來的render()呼叫以及元件重新渲染,反之,返回true時,元件向下走render重新渲染。

所以我們可以在父元件中,重寫這個方法:

shouldComponentUpdate(nextProps, nextState) {
    if (nextState.name !== this.state.name) {
      return true
    }
    return false
  }

讓他在前後name值不相等的時候才繼續重新渲染。

在子元件中,我們這樣寫:

 shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.son !== this.props.son) {
      return true
    }
    return false
  }

表示當傳入的props,當值出現變化的時候才回去重新渲染。
完整的驗證程式碼如下:

import React, { Component } from 'react';

//子元件
class Son extends Component {

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.son !== this.props.son) {
      return true
    }
    return false
  }

  render() {
    console.log("--son--render----")
    return <div> Son: {this.props.son}</div>
  }
}


//父元件,傳給子元件一個on的prop
class App extends Component {
  state = {
    name: 'scarlet',
    son: 2
  }
  componentDidMount() {
    let i = 1;
    setInterval(() => {
      if (i % 5 === 0) {
        console.log("-------------------------", i)
        this.setState({
          name: 'candy',
          son: 9
        })
      } else {
        this.setState({
          name: this.state.name,
          son: this.state.son
        })
      }
      i++
    }, 1 * 1000)
  }
  shouldComponentUpdate(nextProps, nextState) {
    if (nextState.name !== this.state.name) {
      return true
    }
    return false
  }

  render() {
    console.log("--parent--render----")
    return (
      <div className="App">
        <h2>name : {this.state.name}</h2>
        <Son son={this.state.son}></Son>
      </div>
    );
  }
}

export default App;


列印如下:
在這裡插入圖片描述

從列印中可以看出,我們實現了控制,當前後state或者props值不一致的時候,我們才會去進行渲染,從而達到了優化的效果。