React-native入門

搭建開發(fā)環(huán)境

  • 目標(biāo)平臺:IOS
  • 開發(fā)平臺:macOS

安裝

必需的軟件

Homebrew

Homebrew, Mac系統(tǒng)的包管理器耗帕,用于安裝NodeJS和一些其他必需的工具軟件春弥。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

譯注:在Max OS X 10.11(El Capitan)版本中,homebrew在安裝軟件時可能會碰到/usr/local目錄不可寫的權(quán)限問題⊥可以使用下面的命令修復(fù):

sudo chown -R `whoami` /usr/local
Node

使用Homebrew來安裝node.js.

React Native目前需要NodeJS 5.0或更高版本碳竟。本文發(fā)布時Homebrew默認(rèn)安裝的是最新版本种远,一般都滿足要求款筑。

brew install node

安裝完node后建議設(shè)置npm鏡像以加速后面的過程(或使用科學(xué)上網(wǎng)工具)腋么。注意:不要使用cnpm咕娄!cnpm安裝的模塊路徑比較奇怪,packager不能正常識別珊擂!

npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global

Yarn圣勒、React Native的命令行工具(react-native-cli)

Yarn是Facebook提供的替代npm的工具,可以加速node模塊的下載摧扇。React Native的命令行工具用于執(zhí)行創(chuàng)建圣贸、初始化、更新項目扛稽、運(yùn)行打包服務(wù)(packager)等任務(wù)吁峻。

npm install -g yarn react-native-cli

安裝完yarn后同理也要設(shè)置鏡像源:

yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global

如果你看到EACCES: permission denied這樣的權(quán)限報錯,那么請參照上文的homebrew譯注在张,修復(fù)/usr/local目錄的所有權(quán):

sudo chown -R `whoami` /usr/local
Xcode

React Native目前需要Xcode 8.0 或更高版本用含。你可以通過App Store或是到Apple開發(fā)者官網(wǎng)上下載。這一步驟會同時安裝Xcode IDE和Xcode的命令行工具帮匾。

雖然一般來說命令行工具都是默認(rèn)安裝了啄骇,但你最好還是啟動Xcode,并在Xcode | Preferences | Locations菜單中檢查一下是否裝有某個版本的Command Line Tools瘟斜。Xcode的命令行工具中也包含一些必須的工具缸夹,比如git等。

推薦安裝的工具

Watchman

Watchman是由Facebook提供的監(jiān)視文件系統(tǒng)變更的工具螺句。安裝此工具可以提高開發(fā)時的性能(packager可以快速捕捉文件的變化從而實現(xiàn)實時刷新)虽惭。

brew install watchman

Flow

Flow是一個靜態(tài)的JS類型檢查工具。譯注:你在很多示例中看到的奇奇怪怪的冒號問號蛇尚,以及方法參數(shù)中像類型一樣的寫法趟妥,都是屬于這個flow工具的語法。這一語法并不屬于ES標(biāo)準(zhǔn)佣蓉,只是Facebook自家的代碼規(guī)范披摄。所以新手可以直接跳過(即不需要安裝這一工具,也不建議去費(fèi)力學(xué)習(xí)flow相關(guān)語法)勇凭。

brew install flow
vscode

推薦使用vscode疚膊。安裝以下插件:

  • Document this

  • EditorConfig for VS Code

  • EsLint

  • Flow Language Support

  • JavaScript (ES6) code snippets

  • jsx

  • React Native Tools

  • Reactjs code snippet

  • vscode-todo

測試安裝

react-native init AwesomeProject
cd AwesomeProject
react-native run-ios

修改項目

  • 使用你喜歡的編輯器打開index.ios.js并隨便改上幾行。
  • 在iOS Emulator中按下?-R就可以刷新APP并看到你的最新修改虾标!

為已有的React Native工程添加Android支持

如果已經(jīng)有了一個只有IOS版本的React Native工程寓盗,并且希望添加Android支持,需要在工程目錄下運(yùn)行以下命令:

  1. 打開package.json文件,在dependencies項中找到react-native傀蚌,并將其后的版本號修改為最新版本基显。
  2. $ npm install
  3. $ react-native android

動畫

在React Native中,我們已經(jīng)可以聯(lián)合使用兩個互補(bǔ)的系統(tǒng):用于全局的布局動畫LayoutAnimation,和用于創(chuàng)建更精細(xì)的交互控制的動畫Animated.

Animated

Animated僅關(guān)注動畫的輸入與輸出聲明善炫,在其中建立一個可配置的變化函數(shù)撩幽,然后使用簡單的start/stop方法來控制動畫按順序執(zhí)行。

class Playground extends React.Component {
  constructor(props: any) {
    super(props);
    this.state = {
      bounceValue: new Animated.Value(0),
    };
  }
  render(): ReactElement {
    return (
      <Animated.Image                         // 可選的基本組件類型: Image, Text, View
        source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}}
        style={{
          flex: 1,
          transform: [                        // `transform`是一個有序數(shù)組(動畫按順序執(zhí)行)
            {scale: this.state.bounceValue},  // 將`bounceValue`賦值給 `scale`
          ]
        }}
      />
    );
  }
  componentDidMount() {
    this.state.bounceValue.setValue(1.5);     // 設(shè)置一個較大的初始值
    Animated.spring(                          // 可選的基本動畫類型: spring, decay, timing
      this.state.bounceValue,                 // 將`bounceValue`值動畫化
      {
        toValue: 0.8,                         // 將其值以動畫的形式改到一個較小值
        friction: 1,                          // Bouncier spring
      }
    ).start();                                // 開始執(zhí)行動畫
  }
}

bounceValue在構(gòu)造函數(shù)中初始化為state的一部分箩艺,然后和圖片的縮放比例進(jìn)行綁定窜醉。在動畫執(zhí)行的背后,其數(shù)值會被不斷的計算并用于設(shè)置縮放比例艺谆。當(dāng)組件剛剛掛載的時候榨惰,縮放比例被設(shè)置到1.5。然后緊跟著在bounceValue上執(zhí)行了一個彈跳動畫(spring)静汤,會逐幀刷新數(shù)值琅催,并同步更新所有依賴本數(shù)值的綁定(在這個例子里,就是圖片的縮放比例)虫给。比起調(diào)用setState然后重新渲染藤抡,這一運(yùn)行過程要快得多。因為整個配置都是聲明式的狰右,我們可以實現(xiàn)更進(jìn)一步的優(yōu)化,只要序列化好配置舆床,然后我們可以在一個高優(yōu)先級的線程執(zhí)行動畫棋蚌。

核心API

我們所需要的東西都來自于Animated模塊。包括兩個值類型挨队,Value用于單個值谷暮,而ValueXY用于向量值;還包括三種動畫類型盛垦,spring, decay, 還有timing, 以及三種組件類型湿弦,View Text, Image。我們可以使用Animated.createAnimatedComponent方法來對其它類型的組件創(chuàng)建動畫腾夯。

這三種動畫類型可以用來創(chuàng)建幾乎任何你需要的動畫曲線颊埃,因為它們每一個都可以被自定義:

  • spring: 基礎(chǔ)的單次彈跳物理模型

    friction: 摩擦力,默認(rèn)為7.

    tension: 張力蝶俱,默認(rèn)40班利。

  • decay: 以一個初始速度開始并且逐漸減慢停止。

    velocity: 起始速度榨呆,必填參數(shù)罗标。

    deceleration: 速度衰減比例,默認(rèn)為0.997。

  • timing: 從時間范圍映射到漸變的值闯割。

    duration: 動畫持續(xù)的時間(單位是毫秒)彻消,默認(rèn)為500。

    easing:一個用于定義曲線的漸變函數(shù)宙拉。閱讀Easing模塊可以找到許多預(yù)定義的函數(shù)宾尚。iOS默認(rèn)為Easing.inOut(Easing.ease)

    delay: 在一段時間之后開始動畫(單位是毫秒)鼓黔,默認(rèn)為0央勒。

動畫可以通過調(diào)用start方法來開始。start接受一個回調(diào)函數(shù)澳化,當(dāng)動畫結(jié)束的時候會調(diào)用此回調(diào)函數(shù)崔步。如果動畫是因為正常播放完成而結(jié)束的,回調(diào)函數(shù)被調(diào)用時的參數(shù)為{finished: true}缎谷,但若動畫是在結(jié)束之前被調(diào)用了stop而結(jié)束(可能是被一個手勢或者其它的動畫打斷)井濒,它會收到參數(shù){finished: false}

動畫組合

多個動畫可以通過parallel(同時執(zhí)行)列林、sequence(順序執(zhí)行)瑞你、staggerdelay來組合使用。它們中的每一個都接受一個要執(zhí)行的動畫數(shù)組希痴,并且自動在適當(dāng)?shù)臅r候調(diào)用start/stop者甲。舉個例子:

Animated.sequence([            // 首先執(zhí)行decay動畫,結(jié)束后同時執(zhí)行spring和twirl動畫
  Animated.decay(position, {   // 滑行一段距離后停止
    velocity: {x: gestureState.vx, y: gestureState.vy}, // 根據(jù)用戶的手勢設(shè)置速度
    deceleration: 0.997,
  }),
  Animated.parallel([          // 在decay之后并行執(zhí)行:
    Animated.spring(position, {
      toValue: {x: 0, y: 0}    // 返回到起始點(diǎn)開始
    }),
    Animated.timing(twirl, {   // 同時開始旋轉(zhuǎn)
      toValue: 360,
    }),
  ]),
]).start();                    // 執(zhí)行這一整套動畫序列

默認(rèn)情況下砌创,如果任何一個動畫被停止或中斷了虏缸,組內(nèi)所有其它的動畫也會被停止。Parallel有一個stopTogether屬性嫩实,如果設(shè)置為false刽辙,可以禁用自動停止。

跟蹤動態(tài)值

動畫中所設(shè)的值還可以通過跟蹤別的值得到甲献。你只要把toValue設(shè)置成另一個動態(tài)值而不是一個普通數(shù)字就行了宰缤。比如我們可以用彈跳動畫來實現(xiàn)聊天頭像的閃動,又比如通過timing設(shè)置duration:0來實現(xiàn)快速的跟隨晃洒。他們還可以使用插值來進(jìn)行組合:

Animated.spring(follower, {toValue: leader}).start();
Animated.timing(opacity, {
  toValue: pan.x.interpolate({
    inputRange: [0, 300],
    outputRange: [1, 0],
  }),
}).start();

ValueXY是一個方便的處理2D交互的辦法慨灭,譬如旋轉(zhuǎn)或拖拽。它是一個簡單的包含了兩個Animated.Value實例的包裝球及,然后提供了一系列輔助函數(shù)缘挑,使得ValueXY在許多時候可以替代Value來使用。比如在上面的代碼片段中桶略,leaderfollower可以同時為valueXY類型语淘,這樣x和y的值都會被跟蹤诲宇。

輸入事件

Animated.event是Animated API中與輸入有關(guān)的部分,允許手勢或其它事件直接綁定到動態(tài)值上惶翻。它通過一個結(jié)構(gòu)化的映射語法來完成姑蓝,使得復(fù)雜事件對象中的值可以被正確的解開。第一層是一個數(shù)組吕粗,允許同時映射多個值纺荧,然后數(shù)組的每一個元素是一個嵌套的對象。在下面的例子里颅筋,你可以發(fā)現(xiàn)scrollX被映射到了event.nativeEvent.contentOffset.x(event通常是回調(diào)函數(shù)的第一個參數(shù))宙暇,并且pan.xpan.y分別映射到gestureState.dxgestureState.dygestureState是傳遞給PanResponder回調(diào)函數(shù)的第二個參數(shù))。

onScroll={Animated.event(
  [{nativeEvent: {contentOffset: {x: scrollX}}}]   // scrollX = e.nativeEvent.contentOffset.x
)}
onPanResponderMove={Animated.event([
  null,                                          // 忽略原生事件
  {dx: pan.x, dy: pan.y}                         // 從gestureState中解析出dx和dy的值
]);
響應(yīng)當(dāng)前的動畫值

你可能會注意到這里沒有一個明顯的方法來在動畫的過程中讀取當(dāng)前的值——這是出于優(yōu)化的角度考慮议泵,有些值只有在原生代碼運(yùn)行階段中才知道占贫。如果你需要在JavaScript中響應(yīng)當(dāng)前的值,有兩種可能的辦法:

  • spring.stopAnimation(callback)會停止動畫并且把最終的值作為參數(shù)傳遞給回調(diào)函數(shù)callback——這在處理手勢動畫的時候非常有用先口。
  • spring.addListener(callback) 會在動畫的執(zhí)行過程中持續(xù)異步調(diào)用callback回調(diào)函數(shù)型奥,提供一個最近的值作為參數(shù)。這在用于觸發(fā)狀態(tài)切換的時候非常有用碉京,譬如當(dāng)用戶拖拽一個東西靠近的時候彈出一個新的氣泡選項厢汹。不過這個狀態(tài)切換可能并不會十分靈敏,因為它不像許多連續(xù)手勢操作(如旋轉(zhuǎn))那樣在60fps下運(yùn)行谐宙。

LayoutAnimation

LayoutAnimation允許你在全局范圍內(nèi)創(chuàng)建更新動畫烫葬,這些動畫會在下一次渲染或布局周期運(yùn)行。它常用來更新flexbox布局凡蜻,因為它可以無需測量或者計算特定屬性就能直接產(chǎn)生動畫搭综。尤其是當(dāng)布局變化可能影響到父節(jié)點(diǎn)(譬如“查看更多”展開動畫既增加父節(jié)點(diǎn)的尺寸又會將位于本行之下的所有行向下推動)時,如果不使用LayoutAnimation咽瓷,可能就需要顯式聲明組件的坐標(biāo)设凹,才能使得所有受影響的組件能夠同步運(yùn)行動畫舰讹。

注意盡管LayoutAnimation非常強(qiáng)大且有用茅姜,但它對動畫本身的控制沒有Animated或者其它動畫庫那樣方便,所以如果你使用LayoutAnimation無法實現(xiàn)一個效果月匣,那可能還是要考慮其他的方案钻洒。

requestAnimationFrame

requestAnimationFrame是一個對瀏覽器標(biāo)準(zhǔn)API的兼容實現(xiàn),你可能已經(jīng)熟悉它了锄开。它接受一個函數(shù)作為唯一的參數(shù)素标,并且在下一次重繪之前調(diào)用此函數(shù)。一些基于JavaScript的動畫庫高度依賴于這一API萍悴。通常你不必直接調(diào)用它——那些動畫庫會替你管理好幀的更新头遭。

關(guān)于setNativeProps

setNativeProps方法可以使我們直接修改基于原生視圖的組件的屬性寓免,而不需要使用setState來重新渲染整個組件樹。如果我們發(fā)現(xiàn)動畫丟幀计维,可以嘗試使用setNativeProps或者shouldComponentUpdate來優(yōu)化它們袜香。有時候可能還需要將部分計算工作放在動畫完成之后進(jìn)行,這時候可以使用interactionManager

定時器

定時器是一個應(yīng)用中非常重要的部分鲫惶。React Native實現(xiàn)了和瀏覽器一致的定時器Timer蜈首。

定時器

  • setTimeout, clearTimeout
  • setInterval, clearInterval
  • setImmediate, clearImmediate
  • requestAnimationFrame, cancelAnimationFrame

requestAnimationFrame(fn)setTimeout(fn, 0)不同,前者會在每幀刷新之后執(zhí)行一次欠母,而后者則會盡可能快的執(zhí)行(在iPhone5S上有可能每秒1000次以上)欢策。

setImmediate則會在當(dāng)前JavaScript執(zhí)行塊結(jié)束的時候執(zhí)行,就在將要發(fā)送批量響應(yīng)數(shù)據(jù)到原生之前赏淌。注意如果你在setImmediate的回調(diào)函數(shù)中又執(zhí)行了setImmediate踩寇,它會緊接著立刻執(zhí)行,而不會在調(diào)用之前等待原生代碼猜敢。

Promise的實現(xiàn)就使用了setImmediate來執(zhí)行異步調(diào)用姑荷。

InteractionManager

原生應(yīng)用感覺如此流暢的一個重要原因就是在互動和動畫過程中避免繁重的操作。在React Native中缩擂,我們目前受到限制鼠冕,因為我們只有一個JavaScript執(zhí)行線程。不過我們可以使用InteractionManager來確保在執(zhí)行繁重工作之前所有的交互和動畫都已處理完畢胯盯。應(yīng)用可以通過以下代碼來安排一個任務(wù)懈费,使其在交互之后執(zhí)行:

InteractionManager.runAfterInteractions(() => {
  // ...需要長時間同步執(zhí)行
})

我們來把它和之前的幾個任務(wù)安排方法對比一下:

  • requestAnimationFrame(): 用來執(zhí)行在一段時間內(nèi)控制視圖動畫的代碼
  • setImmediate/setTimeout/setInterval(): 在稍后執(zhí)行代碼。注意這有可能會延遲當(dāng)前正在進(jìn)行的動畫博脑。
  • runAfterInteractions(): 在稍后執(zhí)行代碼憎乙,不會延遲當(dāng)前進(jìn)行的動畫。

觸摸處理系統(tǒng)會把一個或多個進(jìn)行中的觸摸操作認(rèn)定為'交互'叉趣,并且會將runAfterInteractions()的回調(diào)函數(shù)延遲執(zhí)行泞边,直到所有的觸摸操作都結(jié)束或取消了。

InteractionManager還允許應(yīng)用注冊動畫疗杉,在動畫開始時創(chuàng)建一個交互“句柄”阵谚,然后在結(jié)束的時候清除它。

var handle = InteractionManager.createInteractionHandle();
// 執(zhí)行動畫... (`runAfterInteractions`中的任務(wù)現(xiàn)在開始排隊等候)
// 在動畫完成之后
InteractionManager.clearInteractionHandle(handle);
// 在所有句柄都清除之后烟具,現(xiàn)在開始依序執(zhí)行隊列中的任務(wù)

TimerMixin

我們發(fā)現(xiàn)很多React Native應(yīng)用發(fā)生致命錯誤(閃退)是與計時器有關(guān)梢什。具體來說,是在某個組件被卸載(unmount)之后朝聋,計時器卻仍然被激活嗡午。為了解決這個問題,我們引入了TimerMixin冀痕。如果你在組件中引入TimerMixin荔睹,就可以把你原本的setTimeout(fn, 500)改為this.setTimeout(fn, 500)(只需要在前面加上this.)狸演,然后當(dāng)你的組件卸載時,所有的計時器事件也會被正確的清除僻他。

這個庫并沒有跟著React Native一起發(fā)布严沥。你需要在項目文件夾下輸入npm i react-timer-mixin --save來單獨(dú)安裝它。

var TimerMixin = require('react-timer-mixin');

var Component = React.createClass({
  mixins: [TimerMixin],
  componentDidMount: function() {
    this.setTimeout(
      () => { console.log('這樣我就不會導(dǎo)致內(nèi)存泄露!'); },
      500
    );
  }
});

注意:Mixin屬于ES5語法中姜,對于ES6來說消玄,無法直接使用Mixin。如果項目使用的是ES6代碼編寫丢胚,同時又使用定時器翩瓜,那么你只需要銘記在unmount組件時清除(clearTimeout/clearInterval)所有用到的定時器,那么也可以實現(xiàn)和TimerMixin同樣的效果携龟。

import React,{
  Component
} from 'react';

export default class Hello extends Component {
  componentDidMount() {
    this.timer = setTimeout(
      () => { console.log('把一個定時器的引用掛在this上'); },
      500
    );
  }
  componentWillUnmount() {
    // 如果存在this.timer兔跌,則使用clearTimeout清空。
    // 如果你使用多個timer峡蟋,那么用多個變量坟桅,或者用個數(shù)組來保存引用,然后逐個clear
    this.timer && clearTimeout(this.timer);  //true&&表達(dá)式   執(zhí)行表達(dá)式
  }
};

直接操作

有時候我們需要直接改動組件并觸發(fā)局部的刷新蕊蝗,但不使用state或是props仅乓。在React Native中,setNativeProps就是等價于直接操作DOM節(jié)點(diǎn)的方法蓬戚。

在(不得不)頻繁刷新而又遇到瓶頸時夸楣,我們會使用setNativeProps;

直接操作組件并不是應(yīng)該經(jīng)常使用的工具。一般來說只是用來創(chuàng)建連續(xù)的動畫子漩,同時避免渲染組件結(jié)構(gòu)和同步太多視圖變化所帶來的大量開銷豫喧。setNativeProps是一個“簡單粗暴”的方法,它直接在底層(DOM幢泼、UIView等)而不是React組件中記錄state,這樣會使代碼邏輯難以理清紧显。所以,我們建議先嘗試用setState和shouldComponentUpdate方法來解決問題缕棵。

setNativeProps與TouchableOpacity

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

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

由此我們可以寫出下面這樣的代碼:子組件可以響應(yīng)點(diǎn)擊事件孵班,更改自己的透明度。而子組件自身并不需要處理這件事情挥吵,也不需要在實現(xiàn)中做任何修改重父。

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

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

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都要重新渲染組件結(jié)構(gòu)矿辽,即便視圖的其他屬性和子組件并沒有變化丹允。一般來說這一開銷也不足為慮郭厌,但當(dāng)執(zhí)行連續(xù)的動畫以及響應(yīng)用戶手勢的時候,只有正確地優(yōu)化組件才能提高動畫的流暢度雕蔽。

如果你看過NativeMethodsMixin.js中的setNativeProps方法的實現(xiàn)折柠,你就會發(fā)現(xiàn)它實際是對RCTUIManager.updateView的封裝 —— 而這正是重渲染所觸發(fā)的函數(shù)調(diào)用,具體可以參看ReactNativeBaseComponent.js中的receiveComponent.

復(fù)合組件與setNativeProps

復(fù)合組件并不是單純的由一個原生視圖構(gòu)成批狐,所以我們不能直接使用setNativeProps扇售。我們可以嘗試這樣去理解:如果是通過React.createClass方法自定義了一個組件,直接給它設(shè)置樣式prop是不會生效的嚣艇,你得把樣式props層層向下傳遞給子組件承冰,直到子組件是一個能夠直接定義樣式的原生組件。同理食零,我們也需要把setNativeProps傳遞給由原生組件封裝的子組件困乒。

將setNativeProps傳遞給子組件

具體的做法就是在我們的自定義組件中再封裝一個setNativeProps方法,它的內(nèi)容為對合適的子組件調(diào)用真正的setNativeProps方法贰谣,并傳遞要設(shè)置的參數(shù)娜搂。

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>
    )
  },
});

現(xiàn)在可以在TouchableOpacity中嵌入MyButton了!

我們在向下傳遞props時使用了{...this.props}語法(這一用法的說明請參考對象的擴(kuò)展運(yùn)算符)吱抚。這是因為TouchableOpacity本身其實也是個復(fù)合組件百宇, 它除了要求在子組件上執(zhí)行setNativeProps 以外,還要求子組件對觸摸事件進(jìn)行處理秘豹。因此恳谎,它會傳遞多個props,其中包含了onmoveshouldsetresponder 函數(shù)憋肖,這個函數(shù)需要回調(diào)給TouchableOpacity組件因痛,以完成觸摸事件的處理。與之相對的是TouchableHighlight組件岸更,它本身是由原生視圖構(gòu)成鸵膏,因而只需要我們實現(xiàn)setNativeProps

setNativeProps與shouldComponentUpdate

通過使用shouldComponentUpdate方法怎炊,可以避免重新渲染那些實際沒有發(fā)生變化的子組件所帶來的額外開銷谭企,此時使用setState的性能已經(jīng)可以與setNativeProps媲美了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末评肆,一起剝皮案震驚了整個濱河市债查,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓜挽,老刑警劉巖盹廷,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異久橙,居然都是意外死亡俄占,警方通過查閱死者的電腦和手機(jī)管怠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缸榄,“玉大人渤弛,你說我怎么就攤上這事∩醮” “怎么了她肯?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鹰贵。 經(jīng)常有香客問我辕宏,道長,這世上最難降的妖魔是什么砾莱? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任瑞筐,我火速辦了婚禮,結(jié)果婚禮上腊瑟,老公的妹妹穿的比我還像新娘聚假。我一直安慰自己,他們只是感情好闰非,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布膘格。 她就那樣靜靜地躺著,像睡著了一般财松。 火紅的嫁衣襯著肌膚如雪瘪贱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天辆毡,我揣著相機(jī)與錄音菜秦,去河邊找鬼。 笑死舶掖,一個胖子當(dāng)著我的面吹牛球昨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眨攘,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼主慰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鲫售?” 一聲冷哼從身側(cè)響起共螺,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎情竹,沒想到半個月后藐不,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年佳吞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棉安。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡底扳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贡耽,到底是詐尸還是另有隱情衷模,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布蒲赂,位于F島的核電站阱冶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滥嘴。R本人自食惡果不足惜木蹬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望若皱。 院中可真熱鬧镊叁,春花似錦、人聲如沸走触。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽互广。三九已至敛腌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惫皱,已是汗流浹背像樊。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旅敷,地道東北人凶硅。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像扫皱,于是被迫代替她去往敵國和親足绅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,734評論 25 707
  • 作為一名Android開發(fā)韩脑,學(xué)習(xí)React Native其實是一個很陡峭的過程氢妈,本文主要記錄自己從接觸React ...
    stefanli閱讀 2,620評論 2 15
  • 概述 隨著app端越來越復(fù)雜,迭代越來越快段多,很多app采用原生+html5的方式來實現(xiàn)首量,然后不知道什么時候,它就有...
    街角仰望閱讀 1,210評論 3 8
  • 背景 隨著各種技術(shù)的發(fā)展,目前市場有各種形式的App加缘,當(dāng)前主要如下幾類: . Web App(SUI鸭叙,MUI,io...
    這個博客有點(diǎn)懶閱讀 282評論 0 1
  • 她叫張夢琪宋下,是個單親孩子,是被爸爸撿回來的辑莫,以前学歧,爸爸的生意很好,家境還不錯各吨≈Ρ浚可是自從那次意外,一切都變了揭蜒。 ...
    LOVE小凱閱讀 184評論 0 1