【REACT NATIVE 系列教程之六】重寫shouldComponentUpdate指定組件是否進行重繪
前幾天,Himi 寫練手項目時,遇到子更新父state中的某一個屬性值,且對父進行重繪時,父包含的所有子組件都進行重繪 – -… 非常尷尬。
查閱了RN文檔,終于在生命周期篇看到了想要的答案。
仔細看過RN關于生命周期篇的童鞋應該知道,就是它:shouldComponentUpdate
官方解釋此函數:
在接收到新的 props 或者 state,將要渲染之前調用。該方法在初始化渲染的時候不會調用,在使用 forceUpdate 方法的時候也不會。
如果確定新的 props 和 state 不會導致組件更新,則此處應該 返回 false。
如果 shouldComponentUpdate 返回 false,則 render() 將不會執行 ,直到下一次 state 改變。(另外,componentWillUpdate 和 componentDidUpdate 也不會被調用。)
默認情況下,shouldComponentUpdate 總會返回 true ,在 state 改變的時候避免細微的 bug,但是如果總是小心地把 state 當做不可變的,在 render() 中只從 props 和 state 讀取值,此時你可以覆蓋 shouldComponentUpdate 方法,實現新老 props 和 state 的比對邏輯。
如果性能是個瓶頸,尤其是有幾十個甚至上百個組件的時候,使用 shouldComponentUpdate 可以提升應用的性能。
那么Himi下面簡單舉例來詳細說明~
一:首先Himi自己定義了一個MyText組件,非常簡單:
importReact, {
AppRegistry,
Component,
Text,
} from 'react-native';
class MyText extends Component {
constructor(props) {
super(props);
this.state = {};
}
shouldComponentUpdate(nextProps, nextState) {
return nextProps.myTextContent === this.props.myTextContent;
}
render() {
return (
<Text> {this.props.myTextContent} </Text>
)
}
}
module.exports = MyText;
這里MyText組件中就包了一個Text組件,且值是通過使用的父使用時進行傳入進來的。
看這么一代碼段:
shouldComponentUpdate(nextProps, nextState) {
return nextProps.myTextContent === this.props.myTextContent;
}
上文介紹過這個函數了,其實如果默認不寫這個函數,默認是跟隨父重繪進行重繪。但是當重寫此函數后,那么就看我們此函數中返回的是true還是false了,如果是true,就是跟著父進行重繪,返回false就是不跟隨更新重新。
這里Himi在此函數中做了一句邏輯代碼,比較上次父傳來的值是否與本次一致,如果一致返回true,反之返回false。
二:嘗試使用MyText代碼:
importReact, {
AppRegistry,
Component,
StyleSheet,
View,
Text,
TouchableHighlight,
} from 'react-native';
importMyTextfrom './MyText'
class AwesomeProject extends Component {
constructor(props) {
super(props);
this.state = {
refreshName :'點擊我進行刷新頁面',
};
}
testEvent(){
this.setState({refreshName:'Himi'});
}
render() {
return (
<Viewstyle={styles.himiViewStyle} >
<Text style={styles.himiTextStyle}>HimiReactNative 教程 </Text>
<Viewstyle={styles.himiViewStyle}>
<TouchableHighlight
underlayColor='#4169e1'
onPress={this.testEvent.bind(this)}
>
<Text style={styles.text} > {this.state.refreshName} </Text>
</TouchableHighlight>
<MyText myTextContent={this.state.refreshName} />
</View>
</View>
)
}
};
var styles = StyleSheet.create({
text: {
color:'#f00',
fontSize:20,
},
himiViewStyle:{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
himiTextStyle:{
color:'#f00',
fontSize:30,
marginTop:70,
},
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
以上主要做了如下功能:
1. 添加一個TouchableHighlight組件用于響應函數,重繪本類下的所有組件。
2. 添加了一個文本Text組件
3. 添加了我們剛才自定義的MyText組件
總結:
1.當觸發響應函數進行重繪所有組件時,正常情況下來說,不論Text還是MyText的內容都應該更改為“Himi”,但是因為MyText重寫了shouldComponentUpdate,且判斷上次與本次傳入的myTextContent內容不同,因此返回false,不重繪本組件。
2.當第二次觸發響應函數進行重繪所有組件時,Text仍舊會被重繪,而且MyText由于shouldComponentUpdate函數中,此時傳入的myTextContent內容與上次傳入的相同(雖然上次沒有重繪,但是myTextContent已被記錄),因此返回true,MyText也會被重繪。
效果如下(點擊查看動態圖):
更多的生命周期詳解,官方鏈接: http://reactjs.cn/react/docs/component-specs.html
來自: http://www.himigame.com/react-native/2252.html