react navite 目录结构
js文件夹
nav.js //在redux里存导航的状态
index.js //合并各个子 reduce
一、"react-navigation": "^1.0.0-beta.22" 低版本的使用
router 文件夹 下建立两个文件夹专门来写导航的页面
1、TabNavigator 专门来写Tab栏上的页面(tab栏上的每个页面的导航都可以在组件中设置,新版本的导航会统一写一个页面)
import React, { Component } from 'react';
import { TabNavigator, TabBarBottom } from 'react-navigation';
import Home from '../components/Home';
import User from '../components/User';
export default (TabNav = TabNavigator({
Home: { screen: Home },
User: { screen: User },
}, {
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
showIcon: true,
animationEnabled: true,
swipeEnabled: false,
tabBarOptions: {
activeTintColor: '#3D3939',
inactiveTintColor: '#3D3939',
},
}));
Tab栏上的每个页面的导航
static navigationOptions = {
header: null,
title: '首页',
tabBarIcon: ({ focused }) => (
),
}
2、AppNavigator 把所有跳转的页面都写在此页面里
import Splash from '../pages/Splash'; // app开屏画面
import TabRouter from './TabRouter'; //tab栏
import Guide from '../guide/guide'; // 引导页
export const AppNavigator = StackNavigator(
{
Splash: { screen: Splash },
tab: { screen: TabRouter },
Guide: { screen: Guide }
}
可以再建立一个页面专门写安卓物理返回键操作(并且在tab栏上可以点击两次退出App)
import React from 'react';
import { addNavigationHelpers, StackNavigator, NavigationActions } from 'react-navigation';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { BackHandler } from "react-native";
import { AppNavigator } from "./AppNavigator";
class App extends React.Component {
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
}
onBackPress = () => {
const { dispatch, nav } = this.props;
if (nav.index === 0) {
return false;
}
dispatch(NavigationActions.back());
return true;
};
render() {
const { dispatch, nav } = this.props;
const navigation = addNavigationHelpers({
dispatch,
state: nav,
});
return ;
}
}
App.propTypes = {
dispatch: PropTypes.func.isRequired,
nav: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
nav: state.nav,
});
export default connect(mapStateToProps)(App);
在安卓上可以使用物理键返回需要redux集成
nav页面(存储导航状态)
import { NavigationActions } from 'react-navigation';
import { AppNavigator } from '../Routers/AppNavigator';
const initialState = AppNavigator.router.getStateForAction(NavigationActions.init());
// ---------reducer---------
export default function nav(state = initialState, action) {
let nextState;
if (action && action.type.indexOf('Navigation/') === 0) {
nextState = AppNavigator.router.getStateForAction(action, state);
}
return nextState || state;
}
在注册页面里引用App组件,就可以实现各个页面的导航以及安卓物理键的使用
二、"react-navigation": "^2.3.0" 新版本的使用
在新版本中很有属性和方法被移除里,使用redux集成,需要下载一个插件react-navigation-redux-helpers
跟旧版本一样,都是建立两个文件存导航页面
1、TabNavigator 专门来写Tab栏上的页面
import Home from '../components/home'; // 底部:首页
import User from '../components/user'; //底部: 我的
const Home = createStackNavigator({
Home: {
screen: Home
navigationOptions: () => ({
title: 首页,
headerBackTitle: null,
header: null,
headerStyle: {
backgroundColor: '#ffffff',
borderBottomWidth: 0
},
headerTitleStyle: {
color: 'rgba(13,14,21,1)',
fontSize: 18
},
headerTintColor: '#000',
borderWidth: 0
})
}
});
const User = createStackNavigator({
User: {
screen: User,
navigationOptions: () => ({
title: 我的,
headerBackTitle: null,
header: null,
headerStyle: {
backgroundColor: '#ffffff',
borderBottomWidth: 0
},
headerTitleStyle: {
color: 'rgba(13,14,21,1)',
fontSize: 18
},
headerTintColor: '#000'
})
}
});
const TabBarPage = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: ({ tintColor, focused }) => (
首页
),
tabBarIcon: ({ focused, tintColor }) =>
),
}
},
User: {
screen: My,
navigationOptions: {
tabBarLabel: ({ tintColor, focused }) => (
我的
),
tabBarIcon: ({ focused, tintColor }) =>
),
}
}
},
{
lazy: true,
animationEnabled: true,
backBehavior: true,
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#3e9ce9',
inactiveTintColor: '#999999',
showIcon: true,
style: {
backgroundColor: '#fff',
height: 98
},
indicatorStyle: {
opacity: 0
},
tabStyle: {
padding: 0
}
}
}
);
2、AppNavigator 把所有跳转的页面都写在此页面里(但是因为更新了版本,在redux集成的时候,做了更多的处理)
import Splash from '../pages/Splash'; // app开屏画面
import TabRouter from './TabRouter'; //tab栏
import Guide from '../guide/guide'; // 引导页
import { createStackNavigator } from 'react-navigation'; // 页面切换 路由导航组件
import { reduxifyNavigator, createReactNavigationReduxMiddleware, createNavigationReducer } from 'react-navigation-redux-helpers';
export const RootNavigator = createStackNavigator(
{
Splash: { screen: Splash },
tab: { screen: TabRouter },
Guide: { screen: Guide }
}
export const middleware = createReactNavigationReduxMiddleware(
'root',
state => state.nav
)
const AppWithNavigationState = reduxifyNavigator(RootNavigator, 'root');
const mapStateToProps = state => ({
state: state.nav
});
const AppNavigator = connect(mapStateToProps)(AppWithNavigationState);
可以再建立一个页面专门写安卓物理返回键操作(并且在tab栏上可以点击两次退出App)
import React from 'react';
import { NavigationActions } from 'react-navigation';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { BackHandler } from "react-native";
import { AppNavigator } from "./AppNavigator";
class App extends Component {
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
}
onBackPress = () => {
const { dispatch, state } = this.props;
if(state.index === 0){
if(this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
Alert.alert('提示','您确定要退出吗?',[
{text: '取消', onPress: () => {return false }},
{text: '确定', onPress: () => { BackHandler.exitApp() }}
])
}
this.lastBackPressed = Date.now();
return true
// return false;
}
dispatch(NavigationActions.back());
return true;
};
render() {
const { dispatch, nav } = this.props;
// const navigation = addNavigationHelpers(); 因为addNavigationHelpers 已被移除不存在
return
}
}
export default connect(mapStateToProps)(App)
nav页面(存储导航状态)这个跟旧的一样
import { NavigationActions } from 'react-navigation';
import { AppNavigator } from '../Routers/AppNavigator';
const initialState = AppNavigator.router.getStateForAction(NavigationActions.init());
// ---------reducer---------
export default function nav(state = initialState, action) {
let nextState;
if (action && action.type.indexOf('Navigation/') === 0) {
nextState = AppNavigator.router.getStateForAction(action, state);
}
return nextState || state;
}
reducer文件下的index页面
import { combineReducers } from 'redux';
import nav from './nav';
export default const reducers = combineReducers({
nav
});
store文件下的index页面
import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk'
import logger from 'redux-logger'
import reducers from './reducers/index';
import { middleware } from "../containers/app";
const store = applyMiddleware(thunk, logger, middleware)(createStore)(reducers);
window.store = store;
export default store;
import { Provider, connect } from 'react-redux';
import React from 'react';
import App from './App';
import { middleware } from './AppNavigator';
import store from './store/index';
class Root extends React.Component {
render() {
return (
);
}
}
。。。以上