好久没写东西了,发现时间过的真快。以前想学习下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的对接外,基本功能都完成了,不过必然还有不少地方作的不正确。因此欢迎一样正在学习的同窗一块儿交流讨论,也欢迎熟手来指导。