使用者主要是透過 Touch 來跟 Mobile App 互動,跟網頁中的 Click 不太一樣。而它又可以結合各種的手勢,長按一個按鈕、滾動 List、放大縮小地圖、Swipe 等等,這邊會簡單介紹到一些相關的 Component。
React Native 內建許多能處理 Touch 的 Component (統稱 Touchables*),它們都能指定 onPress、onPressIn、onPressOut、onLongPress 等等的 Event Handler,而它們之間的差別在於它們被 Touch 之後會有不同的回饋 (Feedback):
TouchableNativeFeedback 只有 Android 能用,而官方也不建議使用 TouchableWithoutFeedback (完全沒有回饋),所以這兩個就先不介紹了。
TouchableHighlight 在被 Touch 之後會有一個 Highlight 的效果,而 Highlight 的顏色可以透過 underlayColor 改變。
<TouchableHighlight
onPress={() => {}}
underlayColor="red"
>
<View style={styles.btn}>
<Text style={styles.text}>按鈕</Text>
</View>
</TouchableHighlight>

更詳細的內容請參閱 TouchableHighlight 的官方文件。
TouchableOpacity 在被 Touch 之後會有一個透明度改變的效果。
<TouchableOpacity
onPress={() => {}}
>
<View style={styles.btn}>
<Text style={styles.text}>按鈕</Text>
</View>
</TouchableOpacity>

更詳細的內容請參閱 TouchableOpacity 的官方文件。
Button 是在v0.37.0 才導入的新 Component,React Naitve 部落格的這篇文章:Introducing Button, Faster Installs with Yarn, and a Public Roadmap 有介紹了它的由來,以往要做出一個跨平台可用的按鈕不夠簡單,而這是 React Native 未來的方向之一,所以才有了它。
<Button
onPress={() => {}}
title="按我啊"
accessibilityLabel="按我啊"
color="red"
disabled={false}
/>

為了簡單明瞭、立即可用,Button 的 API 做出了一些取捨:
onPress,沒有 onPressIn、onLongPress 等等的其他 Handlercolor (在 iOS 是文字顏色、在 Android 是背景顏色) 的客製化,無法設定其他 style
更詳細的內容請參閱 Button 的官方文件。
內容超出一個畫面所能顯示的量時,我們通常需要使用 ScrollView,讓它能藉由往下滑來瀏覽:
<ScrollView>
<Text style={{ fontSize: 60 }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'red' }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'blue' }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60 }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'red' }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'blue' }}>帶給各位滿滿的大平台!</Text>
</ScrollView>

在滑動時,右側會出現滾動軸。(GIF 簡化不少影格,所以會比較不順)
更詳細的內容請參閱 ScrollView 的官方文件。
ListView 通常被用在呈現大量陣列資料時使用,不會一次 Render 所有的 Item,只會 Render 呈現在畫面上的 Item,可以改善單純使用 ScrollView 的效能問題。需要傳遞一個 Function 給 renderRow,讓 ListView 知道怎麼去 Render 每一列。
ListView 的 dataSource Prop 接一個 ListView.DataSource,而產生它的時候要給一個回傳 Boolean 值的 rowHasChanged Function,讓它可以判斷兩個 Row 是不是一樣的:
class ListViewBasics extends Component {
// Initialize the hardcoded data
constructor(props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.state = {
dataSource: ds.cloneWithRows([
'帶給各位!',
'滿滿的!',
'大平台!',
'帶給各位!',
'滿滿的!',
'大平台!',
'帶給各位!',
'滿滿的!',
'大平台!',
'帶給各位!',
'滿滿的!',
'大平台!',
])
};
}
render() {
return (
<View style={{ flex: 1, paddingTop: 22 }}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text style={{ fontSize: 60 }}>{rowData}</Text>}
/>
</View>
);
}
}

更詳細的內容請參閱 ListView 的官方文件。
這些互動相關的 Component 通常是使用者體驗是否良好的關鍵,在使用時也必須特別小心。