好久沒寫東西了,發現時間過的真快。以前想學習下RN,可是因爲本身的懶惰挖了個坑,最近正好公司開了RN的項目,我也把好久之前挖的坑填一下!新開的這個項目只有我一我的搞,以前沒作過RN,此次正好能夠邊作邊學,仍是很開心的,享受這種探索的過程。開始!react
環境搭建好以後,就開始開發了。仍是先大體介紹下這個小項目,此次主要大體會完成如下幾個功能:git
這是目前的項目結構:
github
和以前搭的PC差很少,項目結構都千篇一概,多了一個navigation的文件夾。接下來就介紹這個。npm
最初在搭建RN的項目,主要是參照react-native的文檔,因此不少時候仍是不大清楚到底該用什麼,好比路由。Navigation是網上說起比較多的應用包,所以本項目也使用了這個。redux
本項目用的navigation版本是v2.2.5,你們在用的時候必定要看清楚版本,不一樣版本的api仍是有差別的,而後去看英文的文檔,這裏我還被坑了一下。ubuntu
navigation的路由入口是由一個StackNavigator建立的,也就如名字同樣是一個堆棧式的路由數據,在2.2.5版本已經由StackNavigator變爲createStackNavigator了。目前app只作了一個主頁面和一個二維碼掃描的跳轉頁。即:react-native
const AppNavigator = createStackNavigator( { Home: { screen: MainScreenNavigator, navigationOptions: { title: '首頁' } }, QRcode: { screen: QRcode, navigationOptions: { header: null } } } );
主要的頁面都寫在了MainScreenNavigator。api
MainScreenNavigator用了一般app採用的底部tab的呈現方法,界面預覽:
微信
在navigation中主要有兩種導航的表現形式,一種是Tab navigation,另外一種是Drawer navigation,這裏採用的tab的表現方式,而drawer 相似於側邊抽出的,目前尚未用到。目前下方的tab主要分爲5個,即:app
const MainScreenNavigator = createMaterialBottomTabNavigator( { Home: { screen: Home, navigationOptions: { title: '首頁', tabBarIcon: tabBarIcon('home') } }, Photo: { screen: Photo, navigationOptions: { title: '拍照', tabBarIcon: tabBarIcon('photo-album') } }, NFC: { screen: Setting, navigationOptions: { title: 'NFC', tabBarIcon: tabBarIcon('credit-card') } }, Upload: { screen: Upload, navigationOptions: { title: '上傳', tabBarIcon: tabBarIcon('cloud-upload'), } }, Setting: { screen: Setting, navigationOptions: { title: '設置', tabBarIcon: tabBarIcon('settings') } } }, { shifting: true, backBehavior: 'none', initialRouteName: 'Home', activeTintColor: '#ffffff', inactiveTintColor: '#eeeeee', barStyle: { backgroundColor: '#4177F6', paddingBottom: 20, height: 50 } } );
這個tab用到了他官方推薦的一個react-navigation-material-bottom-tabs
插件,在使用這個插件時須要去引入icons,我這裏引入的是這個。
順便說一下,react-native推薦的包管理工具是yarn,最好使用yarn能夠省不少事,由於我這邊(ubuntu16.04)若是用npm安裝的話,就不能正常使用react link xx的功能,link是幫咱們自動去關聯一些依賴以及gradle的。
navigation的一些配置能夠在creat的時候去寫,好比聲明一個tab的名稱爲上傳。
Upload: { screen: Upload, navigationOptions: { title: '上傳', tabBarIcon: tabBarIcon('cloud-upload'), } },
也能夠在具體的業務組件裏面去定義靜態方法,如:
class Upload extends PureComponent { static navigationOptions = { tabBarOnPress: async ({ defaultHandler, navigation }) => { const { navigate } = navigation; const files = await storageFile(); navigate('Upload', { files }); } }; }
好比在點擊Upload的tab時,去觸發一個存儲文件的方法(storageFile是自定義的方法)。
這裏我我的以爲一些靜態的title,或者樣式上的配置,就直接在總的MainScreenNavigator中寫好就好了,而涉及到一些具體的業務需求,方法,就在具體的組件模塊裏去寫,比較方便管理和維護。
navigation大致介紹到這裏,以後有在項目中新增的東西,會繼續同步過來。
最初在項目搭建的時候,仍是像將redux引入react 的方式,去引入到react-native的。即用react-redux提供的Provider在根頁面將app包裹起來,而後去把reducer注入到store當中去。可是有些狀況下,可能須要navigation的配合,所以須要去整合navigation進來。
在navigation v2.2.5中將不少api獨立了出來,單獨分了一個react-navigation-redux-helpers
的模型。大致思路仍是沒有變,根頁面引入react-redux。
import React, { Component } from 'react'; import { Provider } from 'react-redux'; import store from './redux/store'; import Navigation from './navigation'; import { YellowBox } from 'react-native'; YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated', 'Module RCTImageLoader']); class App extends Component { render() { return ( <Provider store={store}> <Navigation /> </Provider > ); } } export default App;
在store當中增長對navigation的整合:
import { createStore, combineReducers, applyMiddleware } from 'redux'; import * as reducer from '../reducer/'; import thunk from 'redux-thunk'; import AppNavigator from '../../navigation/route'; import { createNavigationReducer, createReactNavigationReduxMiddleware } from "react-navigation-redux-helpers"; // 中間件,有了這個就能夠支持異步action const navReducer = createNavigationReducer(AppNavigator); const middleware = createReactNavigationReduxMiddleware( "root", state => state.nav ); const store = createStore( combineReducers({ ...reducer, nav: navReducer }), applyMiddleware(middleware) ); export default store;
navigation組件去作一些初始屬性的配置:
import React, { Component } from 'react'; import { connect } from 'react-redux'; import { createNavigationPropConstructor, // handles #1 above initializeListeners, // handles #4 above } from 'react-navigation-redux-helpers'; import AppNavigator from './route.js'; const navigationPropConstructor = createNavigationPropConstructor("root"); class Navigation extends Component { componentDidMount() { initializeListeners("root", this.props.nav); } render() { this._navigation = navigationPropConstructor( this.props.dispatch, this.props.nav, AppNavigator.router, () => this._navigation ); return ( <AppNavigator navigation={this._navigation} /> ); } } const mapStateToProps = (state) => ({ nav: state.nav, }); export default connect(mapStateToProps)(Navigation);
關於navigation+redux我這裏就沒有去細講了,由於本身也是徹底去照搬官方文檔,若是有同窗去作到這一塊的話,以官方文檔爲參考就ok。
在作navigation這一塊,我的感受仍是比較簡單好理解的,惟一很差的地方是版本之間差別較大,最初v2.2.5開發完以後,去從新下載項目依賴,navigation往上升了2個小版本,結果就不行了,而這中間也就隔了3,4天而已,因此配置相關的東西仍是要去看最新的文檔。
目前這個項目本身作了一個星期左右,大致功能除了地圖sdk的對接外,基本功能都完成了,不過必然還有不少地方作的不正確。因此歡迎一樣正在學習的同窗一塊兒交流討論,也歡迎熟手來指導。