【REACT NATIVE 系列教程之六】重寫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也會被重繪。

效果如下(點擊查看動態圖):

user25

更多的生命週期詳解,官方鏈接:http://reactjs.cn/react/docs/component-specs.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章