這個項目對應的場景對于我們應用開發來說很常見:
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訪問)。
新聞熱點
疑難解答