【React】使用shouldComponentUpdate對元件效能進行優化
阿新 • • 發佈:2018-11-11
前言
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值不一致的時候,我們才會去進行渲染,從而達到了優化的效果。