React Native 之 setNativeProps

在React Native 中,改變組件的布局樣式等可以通過props或者state來實現,但由于性能瓶頸,我們不得不放棄通過觸發render的方式來改變樣式,而是通過setNativeProps來直接更改原生組件的樣式屬性來達到相同的效果。

這里的setNativeProps方法等價于直接操作DOM節點的方法。使用這種方法修改View、Text等react Native自帶的組件,并且不會觸發組件的componentWillReceivePropsshouldComponentUpdatecomponentWillUpdate 等組件生命周期中的方法。但它不應該經常被使用,一般建議在不得不頻繁刷新而又遇到了性能瓶頸時使用。建議在使用此方法之前優先考慮setState和shouldComponentUpdate方法來解決問題。

setNativeProps 與 TouchableOpacity

TouchableOpacity這個組件就在內部使用了setNativeProps方法來更新其子組件的透明度:

setOpacityTo: function(value) {
  // Redacted: animation related code
  this.refs[CHILD_REF].setNativeProps({
    opacity: value
  });
},

由此我們可以寫出下面這樣的代碼:子組件可以響應點擊事件,更改自己的透明度。而子組件自身并不需要處理這件事情,也不需要在實現中做任何修改。

<TouchableOpacity onPress={this._handlePress}>
  <View style={styles.button}>
    <Text>Press me!</Text>
  </View>
</TouchableOpacity>

如果不使用setNativeProps這個方法來實現這一需求,那么一種可能的辦法是把透明值保存到state中,然后在onPress事件觸發時更新這個值:

getInitialState() {
  return { myButtonOpacity: 1, }
},

render() {
  return (
    <TouchableOpacity onPress={() => this.setState({myButtonOpacity: 0.5})}
                      onPressOut={() => this.setState({myButtonOpacity: 1})}>
      <View style={[styles.button, {opacity: this.state.myButtonOpacity}]}>
        <Text>Press me!</Text>
      </View>
    </TouchableOpacity>
  )
}

比起之前的例子,這一做法會消耗大量的計算 —— 每一次透明值變更的時候React都要重新渲染組件結構,即便視圖的其他屬性和子組件并沒有變化。一般來說這一開銷也不足為慮,但當執行連續的動畫以及響應用戶手勢的時候,只有正確地優化組件才能提高動畫的流暢度。

將setNativeProps傳遞給子組件

具體要做的就是在我們的自定義組件中再封裝一個setNativeProps方法,其內容為對合適的子組件調用真正的setNativeProps方法,并傳遞要設置的參數。

var MyButton = React.createClass({
  setNativeProps(nativeProps) {
    this._root.setNativeProps(nativeProps);
  },

  render() {
    return (
      <View ref={component => this._root = component} {...this.props}>
        <Text>{this.props.label}</Text>
      </View>
    )
  },
});

這里我們使用了ref回調語法,我們向下傳遞props時使用了{...this.props}語法,(這一用法的說明請參考對象的擴展運算符),這是因為復合組件除了要求在子組件上執行setNativeProps意外,還要求子組件對觸摸事件進行處理,因此會傳遞多個props.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 深入JSX date:20170412筆記原文其實JSX是React.createElement(componen...
    gaoer1938閱讀 8,106評論 2 35
  • 原教程內容詳見精益 React 學習指南,這只是我在學習過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,860評論 1 18
  • 前言 本文 有配套視頻,可以酌情觀看。 文中內容因各人理解不同,可能會有所偏差,歡迎朋友們聯系我討論。 文中所有內...
    珍此良辰閱讀 11,947評論 23 111
  • 溪水在彈奏小鳥在歌唱 花草在跳舞樹木是觀眾 你在其中游走
    心花園子閱讀 222評論 0 2
  • 在以十年、二十年、三十年乃至更久的時間尺度上,伴隨一餅新茶從青澀到甘醇,從濃烈到敦厚,它陪伴你完成了一生的醇化與升...
    茶雲澗閱讀 347評論 0 0