先贴上最终成果代码地址:https://gitee.com/wuchunling/reactNativeApp.git
再贴上最终最终成果效果图:(在Android模拟器运行效果图)
reactNativeApp
项目介绍
这是一个搭建好的react native项目架构,采用react-native官方推荐的react-navigation导航库,项目StackNavigator与TabNavigator相结合使用。http请求采用axios库,并且自己封装好请求函数。数据管理采用redux。
软件架构
安装依赖包
react / react-native / axios /redux / react-navigation
redux-thunk / react-redux react-native-button / react-native-storage
安装教程
- npm install 安装依赖包
- 运行模拟器
- react-native start
- react-native run-android / react-native run-ios
使用说明
- 安卓设备reload JS:双击R
- IOS设备reload JS:Cmd+R
项目代码结构
- App.js 根组件
- index.js 入口文件
- src
- api API接口文件夹
- assets 静态资源文件夹
- components 组件文件夹
- redux 状态管理文件夹
- actions 文件夹,存放各个模块的action
- reducers 文件夹,存放各个模块的reducer
- services 文件夹,存放各个模块的http请求接口
- reducer.js 根reducer文件-combineReducers for rootReducer
- store.js 项目store文件 - createStore(reducer,applyMiddleware(thunk))
- routers
- index.js 项目所有路由配置
- tab.js 底栏tabbar路由配置
- utils 工具文件夹
- views 页面级组件文件夹
以下进入正题,从零开始搭建我的react-native项目(这花费了我三天时间,之前从未接触过react-native,半天看react-native教程,一天搭环境,一天半写代码)
一、前期准备工具
1. 配置好 jdk
2. 配置好 sdk
3. 下载好模拟器(我是下载了Android Studio,直接使用里面的模拟器)
4. 开发工具Atom,作为一个前端人员,真的不习惯用Android Studio编写代码,我还是继续用回我的Atom。改完代码Ctrl+S,再在模拟器上双击R,代码立即更新,要多方便有多方便,AS这烦人的东西根本用不着。
二、项目初始化
按照官网指示:react-native init MyProject
三、运行模拟器(一定要先运行模拟器,等你跑项目的时候模拟器会自动打开你跑的项目)
四、跑项目啦:
react-native start 这一步是 Loading dependency graph,显示done的时候就可以执行下一步指令
react-native run-android build成功的话模拟器会自动打开项目
可能跑完一堆爆红,项目没办法运行,这时候就看报错,一步一步排查,直到解决错误,看到 react-native的欢迎界面。接下来才可以进行代码的开发。
一般的报错有 sdk platforms 版本问题,sdk platform-tools版本问题或sdk build-tools版本问题等等。根据提示去下载对应的版本即可。这里贴一个牛逼的地址,有各种版本供下载:http://mirrors.neusoft.edu.cn/android/repository/
等项目运行成功就可以开始搭建自己的项目架构了。
第一步,安装所需依赖包
axios / redux / react-navigation / ……等等
第二步,随意编写几个页面级组件供测试用
Home/Goods/Me/Orders,以Home举例
import React from 'react'
import {Text} from 'react-native'
class Home extends React.Component{
render(){
return(
<Text>首页</Text>
)
}
}
export default Home;
第三步,配置 tabbar的路由 src/routers/tab.js
import React from 'react';
import {createBottomTabNavigator} from 'react-navigation';
import Home from '../views/Home'
import Me from '../views/Me'
import Goods from '../views/Goods'
import Orders from '../views/Orders'
const TabNav = createBottomTabNavigator(
{
Home:{screen:Home},
Goods:{screen:Goods},
Orders:{screen:Orders},
Me:{screen:Me},
},{
initialRouteName: 'Home',
tabBarOptions:{
activeTintColor: '#FF7900', //当前选中的tab bar的文本颜色和图标颜色
inactiveTintColor: '#b2b2b2', //当前未选中的tab bar的文本颜色和图标颜色
showIcon: true, //是否显示tab bar的图标,默认是false
pressOpacity: 0.8, //按下tab bar时的不透明度(仅支持iOS和Android < 5.0).
style: { //tab bar的样式
backgroundColor: '#fff',
paddingBottom: 2,
paddingTop:2,
borderTopWidth: 0.1,
borderTopColor: '#b2b2b2',
}
}
}
);
export default TabNav;
第四步:修改第二步创建的页面级组件,为它加上tabbar的icon图标和tabbar的textlabel,以Home举例
import React from 'react'
import {Text,Image,StyleSheet} from 'react-native'
class Home extends React.Component{
static navigationOptions = {
tabBarLabel: '首页',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<Image style={styles.tabBarIcon} source={require('../assets/navbar-home-icon-active.png')}/>
);
}
return (
<Image style={styles.tabBarIcon} source={require('../assets/navbar-home-icon.png')}/>
);
},
};
render(){
return(
<Text>首页</Text>
)
}
}
const styles = StyleSheet.create({
tabBarIcon:{
width:24,height:24
}
});
export default Home;
第五步:创建非tabbar页面的页面级组件Apples
import React from 'react'
import {Text} from 'react-native'
class Apples extends React.Component{
render(){
return(
<Text>苹果篮子</Text>
)
}
}
export default Apples;
第六步:创建根路由文件 src/routers/index.js
import { StackNavigator } from 'react-navigation';
import TabNav from './tab'
import Apples from '../views/Apples'
const AppNavigator = StackNavigator({ //整个应用的路由栈
TabBar: {
screen: TabNav,
navigationOptions: ({navigation}) => ({
header: null
})
},
Apples: {screen: Apples}
}
);
export default AppNavigator;
第七步:修改根组件 App.js
注释掉部分为redux接入,稍后再讲。
import React, {Component} from 'react';
import { Provider } from 'react-redux';
//import store from './src/redux/store';
import AppNavigator from './src/routers/index'
export default class App extends Component{
render(){
return(
// <Provider store={store}>
<AppNavigator/>
// </Provider>
)
}
}
第八步:在Home页面加入跳转,跳转到Apple
import React from 'react'
import { View,StyleSheet,Text,Image,Button } from 'react-native'
class Home extends React.Component{
static navigationOptions = {
tabBarLabel: '首页',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<Image style={styles.tabBarIcon} source={require('../assets/navbar-home-icon-active.png')}/>
);
}
return (
<Image style={styles.tabBarIcon} source={require('../assets/navbar-home-icon.png')}/>
);
},
};
render(){
const {navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Text>首页</Text>
<Button
onPress={() => navigate('Apples', {name: 'Brent'})}
title="苹果篮子"
/>
</View>
)
}
}
const styles = StyleSheet.create({
tabBarIcon:{
width:24,height:24
},
container:{
padding:30
}
});
export default Home;
这样,路由就配置完成!至于redux的接入,跟react接入redux是一样的操作,可以参考上一篇文章【React】React全栈脚手架搭建-苹果篮子示例,去编写对应的 action / reducer / service。这部分代码react是什么样,react-native就是什么样,无需变化。变化的是组件的编写,组件名跟样式写法变了,其余逻辑部分都是保持不变。
redux的结构可以如下。当然如果项目过大,更推荐以模块去分文件夹,把每个模块的action/reducers/services放在一起。
根级store.js的编写
import {createStore,applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
let store = createStore(reducer,applyMiddleware(thunk))
export default store;
根级reducer.js的编写
import { combineReducers } from 'redux';
import appleReducer from './reducers/appleReducer';
const rootReducer = combineReducers({
appleBasket: appleReducer
});
export default rootReducer;
最后只要在根组件App.js通过Provider注入store即可
import React, {Component} from 'react';
import { Provider } from 'react-redux';
import store from './src/redux/store';
import AppNavigator from './src/routers/index'
export default class App extends Component{
render(){
return(
<Provider store={store}>
<AppNavigator/>
</Provider>
)
}
}
这样,一个完善的具有路由,状态,请求的react-native项目就搭建完成。