這個項目對應的場景對于我們應用開發來說很常見:
1. 通過網絡api或其他途徑獲取到數據源(是一個列表)
2. 通過一個列表簡單呈現主要信息,列表可點擊進入瀏覽詳情
3. 詳情頁面接收了來自上個頁面傳遞來的數據,并作一個相對完整的展示;那么這個過程中自然就需要一個導航欄
截圖如下:


其中所使用的主要rn技術點歸納如下:
1. 通過fetch函數進行網絡請求。
_refreshData() { fetch(ENDPOINT) .then((response) => response.json()) .then((rjson) => { this.setState({ dataSource1: this.state.dataSource1.cloneWithRows(rjson.results.books) }); }); }該函數在componentDidMount中被調用。2.導航欄實現,并通過它來傳值(類似iOS中那種一直在上面顯示的導航條);注意,這里使用的是rn提供的跨平臺導航器Navigator。
/** * Sample React Native App * https://github.com/facebook/react-native */import React, { Component } from 'react';import { ApPRegistry, StyleSheet, Text, View, Image, ListView , TextInput, Platform, TouchableOpacity, Navigator} from 'react-native';import NoteMain from './NoteMain';// 設置默認的路由,也就是ROOTNAV的第一個vc.const defaultRoute ={ component: NoteMain, title: "列表頁"};class rootNav extends Component{ // 繪制場景的方法; 可以得到路由和nav的實例;這里從route獲取到component (route對象內有很多內容,全部傳遞給component); // 同時將navigator作為屬性繼續傳遞到vc中,否則后續vc無法調用this.props.navigator // 注意,這里的info為空,暫時沒有傳遞任何數據。 _renderScene(route, navigator) { console.log ('_renderSceneing in rootNav'); console.log(route); console.log(route.info); let Component = route.component; return ( <Component {...route.info} navigator={navigator} /> ); } // 繪制navBar,并在每一個nav下的頁面展示 _renderNavBar() { const styles = { title: { flex: 1, alignItems: 'center', justifyContent: 'center' }, button: { flex: 1, width: 50, alignItems: 'center', justifyContent: 'center' }, buttonText: { fontSize: 18, color: '#FFFFFF', fontWeight: '400' } } var routeMapper = { LeftButton(route, navigator, index, navState) { console.log ('index='+ index); if(index > 0) { return ( <TouchableOpacity onPress={() => navigator.pop()} style={styles.button}> <Text style={styles.buttonText}>Back</Text> </TouchableOpacity> ); } }, // 這個目前沒有卵用,等后面加的時候再看。 RightButton(route, navigator, index, navState) { // 默認的pop if(index > 0 && route.rightButton) { return ( <TouchableOpacity onPress={() => navigator.pop()} style={styles.button}> <Text style={styles.buttonText}></Text> </TouchableOpacity> ); } else { return null } }, Title(route, navigator, index, navState) { return ( <View style={styles.title}> <Text style={styles.buttonText}>{route.title}</Text> </View> ); } }; return ( <Navigator.NavigationBar style={{ alignItems: 'center', backgroundColor: '#55ACEE', shadowOffset:{ width: 1, height: 0.5, }, shadowColor: '#55ACEE', shadowOpacity: 0.8, }} routeMapper={routeMapper} /> ); } render() { console.log ('app rendering'); return ( <Navigator initialRoute={defaultRoute} renderScene={this._renderScene} sceneStyle={{paddingTop: 64}} navigationBar={this._renderNavBar()} /> ); }}const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, },});3. listview的簡單使用,在列表元素中使用TouchableOpacity來響應事件;4. view/image/text/touchableopacity的簡單使用和嵌套;
5. 結合flex和width/height進行布局; style實現樣式;...的方式來快速傳值(屬性);
6. 注意this的傳遞,在不使用箭頭函數綁定的情況下,函數內容若要使用this則需要在外部bind(this).
7. 何時封裝組件;如何封裝簡單組件;PropTypes來限定類型。
主要技術點就這些,是一個最基礎的實現,代碼大約300多行,這里的api需要翻墻才能訪問(iOS項目還需要在plist里面允許http訪問)。
新聞熱點
疑難解答