我們知道當state更新時,界面會重新繪製,render會被執行,但是一個界面包含許多控件,state更新導致界面重繪,那麼是否所有的控件都重繪呢?
驗證
通過一個點擊事件來改變state的值,然後看看界面有什麼變化,代碼如下:
import React,{Component} from 'react';
import {
View,
TouchableOpacity,
Text,
} from 'react-native';
export default class Test extends Component{
constructor(props){
super(props);
this.state = ({
count:0,
});
}
_onPress(){
var count = this.state.count + 1;
this.setState({
count:count,
});
}
render(){
return(
<View>
<TouchableOpacity onPress={this._onPress.bind(this)}>
<Text>刷新界面{this.state.count}</Text>
</TouchableOpacity>
<Test2 />
</View>
);
}
}
//定義另一個組件Test2,被Test所引用
class Test2 extends Component{
render(){
console.log('Test2 render');
return(
<View>
<Text>Test2</Text>
</View>
);
}
}
點擊‘刷新界面’,可以看到Test下的Text內容改變了,Test2的日誌也有輸出,說明在這種情況下,state的改變,會重寫執行render,使界面重新繪製,並且所有子控件默認都會重新繪製。可是你發現Test2只是固定顯示一個文本,那麼即使再重新繪製它還是不變的,這樣就做了無用功,浪費了界面渲染時間。所以,是否可以優化這種state帶來的界面重新渲染的性能問題呢?答案是有的。
每個Component都有一個函數shouldComponentUpdate,這個函數返回是否需要更新組件。當state的值有變化時,先執行此方法,此返回值爲true/false,判斷是否執行更新操作,即是否執行render渲染。那麼,在我們這個例子中,Test2組件只是顯示一個固定的文本,所以返回一個false即可。
class Test2 extends Component{
shouldComponentUpdate(nextProps,nextState){
//寫自己的邏輯判斷是否需要更新組件
return false;
}
render(){
console.log('Test2 render');
return(
<View>
<Text>Test2</Text>
</View>
);
}
}
總結
在項目開發的過程中,我們總會自定義一些組件,這些組件總會被其他組件所引用,在知道了state的刷新問題之後,重寫shouldComponentUpdate這個函數,對我們來說格外重要,可以讓我們清楚的明白,這個組件什麼情況下需要被更新,什麼情況下不需要更新。這樣做的好處就是,可以大大的提高界面的刷新速度,而這不就是我們所追求的嗎!