標籤:react native himi shouldcomponentupdate 組件 重繪
本站文章均為 李華明Himi 原創,轉載務必在明顯處註明:
轉載自【黑米GameDev街區】 原文連結: http://www.himigame.com/react-native/2252.html
前幾天,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組件,非常簡單:
import React, { 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代碼:
import React, { AppRegistry, Component, StyleSheet, View, Text, TouchableHighlight,} from ‘react-native‘; import MyText from ‘./MyText‘ class AwesomeProject extends Component { constructor(props) { super(props); this.state = { refreshName :‘點擊我進行重新整理頁面‘, }; } testEvent(){ this.setState({refreshName:‘Himi‘}); } render() { return ( <View style={styles.himiViewStyle} > <Text style={styles.himiTextStyle}>Himi React Native 教程 </Text> <View style={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也會被重繪。
效果如下(點擊查看動態圖):
650) this.width=650;" class="alignnone size-medium wp-image-2253" src="http://www.himigame.com/wp-content/uploads/2016/05/user25-162x300.gif" alt="user25" width="162" height="300" style="margin:0px;padding:1px;border:1px solid rgb(97,146,140);font-family:inherit;font-size:inherit;font-style:inherit;line-height:inherit;height:auto;" />
更多的生命週期詳解,官方連結:http://reactjs.cn/react/docs/component-specs.html
本文出自 “李華明Himi” 部落格,請務必保留此出處http://xiaominghimi.blog.51cto.com/2614927/1783127
【REACT NATIVE 系列教程之六】重寫SHOULDCOMPONENTUPDATE指定組件是否進行重繪