【React Native】文件翻譯閱讀紀錄 - 指南 - 直接操縱

by - 上午9:00

Facebook Open Source React Native



直接操縱

有時需要直接對組件進行更改,而不使用state / props來觸發重新呈現整個子樹。例如,在瀏覽器中使用React時,有時需要直接修改DOM節點,對於移動應用程序中的視圖也是如此。 setNativeProps是React Native,相當於直接在DOM節點上設置屬性。

頻繁重新渲染會產生性能瓶頸時,請使用 setNativeProps

直接操作不會成為您頻繁使用的工具;您通常只會使用它來創建連續動畫,以避免渲染組件層次結構和協調許多視圖的開銷。 setNativeProps 是必不可少的,並且將狀態存儲在本機層(DOM,UIView等)中,而不是存儲在 React組件中,這使得您的代碼更難以推理。在使用它之前,嘗試使用 setState 和shouldComponentUpdate 解決您的問題。

使用T ouchableOpacity 設置 setNativeProps

TouchableOpacity 在內部使用setNativeProps來更新其子組件的不透明度:
setOpacityTo(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不可用。我們可以使用該約束實現它的一種方法是將不透明度值存儲在狀態中,然後在onPress被觸發時更新該值:
constructor(props) {
  super(props);
  this.state = { 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都需要重新呈現組件層次結構,即使視圖及其子項的其他屬性未更改也是如此。通常這種開銷不是問題,但在執行連續動畫和響應手勢時,明智地優化組件可以提高動畫的保真度。

如果你看一下 NativeMethodsMixin.js 中 setNativeProps 的實現,你會發現它是RCTUIManager.updateView 的包裝器 - 這是與重新渲染產生的完全相同的函數調用 - 請參閱 ReactNativeBaseComponent.js 中的receiveComponent。

複合組件和 setNativeProps

複合組件不受本機視圖支持,因此您無法在它們上調用setNativeProps。考慮這個例子:

如果您運行此命令,您將立即看到此錯誤:可觸摸的子項必須是本機或將setNativeProps轉發到本​​機組件。發生這種情況是因為MyButton不是由應設置不透明度的本機視圖直接支持。您可以這樣考慮:如果您使用createReactClass定義一個組件,您將不希望能夠在其上設置樣式道具並使其工作 - 您需要將樣式道具傳遞給孩子,除非您是包裝本機組件。同樣,我們將把setNativeProps轉發給本機支持的子組件。

將 setNativeProps 轉發給子元件

我們需要做的就是在我們的組件上提供一個setNativeProps方法,該方法使用給定的參數調用相應子節點上的setNativeProps。

您現在可以在TouchableOpacity中使用MyButton!清晰的旁注:我們在這裡使用了ref回調語法,而不是傳統的基於字符串的ref。

您可能已經註意到我們使用{... this.props}將所有道具傳遞到子視圖。原因是TouchableOpacity實際上是一個複合組件,因此除了依賴其子組件上的setNativeProps之外,它還要求子組件執行觸摸處理。為此,它會傳遞回調到TouchableOpacity組件的各種道具。相比之下,TouchableHighlight由本機視圖支持,只需要我們實現setNativeProps。

setNativeProps 清除 TextInput 值

setNativeProps的另一個非常常見的用例是清除TextInput的值。當bufferDelay為低並且用戶輸入非常快時,TextInput的受控prop可能有時會丟棄字符。一些開發人員更喜歡完全跳過此prop,而是使用setNativeProps在必要時直接操作TextInput值。例如,以下代碼演示了當您點擊按鈕時清除輸入:

避免與渲染功能發生衝突

如果更新也由render函數管理的屬性,則最終可能會出現一些不可預測且令人困惑的錯誤,因為只要組件重新呈現並且該屬性發生更改,以前從setNativeProps設置的任何值都將被完全忽略和覆蓋。

setNativeProps & shouldComponentUpdate

通過智能地應用shouldComponentUpdate,您可以避免協調未更改的組件子樹所涉及的不必要的開銷,使其可能具有足夠的性能來使用setState而不是setNativeProps。

其他原生方法

此處描述的方法可用於React Native提供的大多數默認組件。但請注意,它們不適用於未由本機視圖直接支持的複合組件。這通常包括您在自己的應用中定義的大多數組件。

measure(callback)

確定給定視圖的屏幕,寬度和高度的位置,並通過異步回調返回值。如果成功,將使用以下參數調用回調:
  • x
  • y
  • width
  • height
  • pageX
  • pageY
請注意,在本機完成渲染之後,這些測量才可用。如果您需要盡快進行測量,請考慮使用onLayout道具。

measureInWindow(callback)

確定窗口中給定視圖的位置,並通過異步回調返回值。如果React根視圖嵌入在另一個本機視圖中,這將為您提供絕對坐標。如果成功,將使用以下參數調用回調:
  • x
  • y
  • width
  • height

measureLayout(relativeToNativeNode, onSuccess, onFail)

與measure()類似,但測量相對於祖先的視圖,指定為relativeToNativeNode。這意味著返回的x,y相對於祖先視圖的原點x,y。
與往常一樣,要獲取組件的本機節點句柄,可以使用 ReactNative.findNodeHandle(component).

focus()

請求關注給定的輸入或視圖。觸發的確切行為將取決於平台和視圖類型。

blur()

從輸入或視圖中移除焦點。這與focus() 相反。



You May Also Like

0 意見