react-native结合react-navigation之TabNavigator

简介: react-native开发需时肯定有tab的切换,或者页面的转调,当然用RN自身的Navigator 也可以但是也不是那么方便react-navigation 就能满足很多大部分需求,如...

react-native开发需时肯定有tab的切换,或者页面的转调,当然用RN自身的Navigator 也可以但是也不是那么方便react-navigation 就能满足很多大部分需求,如下图的三种切换方式,下面就说下TabNavigator 和StackNavigator的应用,才踏的一个坑,还是太年轻呀,横刀一撸!!!!

主要的界面 用tab 切换即是TabNavigator, 切换如下图


一共四个页面当然配置就如下咯

// 两个参数 routeConfigs: NavigationRouteConfigMap,  config: TabNavigatorConfig = {}
// 一个route对应的页面和tab图标, 一个切换的样式整个tab栏的样式
//tab
export const AppNavigator = TabNavigator({
	Hotshow: {screen: hotshow, navigationOptions: {
		tabBarLabel: '热映',
		tabBarIcon: ({ tintColor, focused }) => (
			<Image resizeMode='contain'
				source={require('../icon/icon_hot.png')}
				style={[style.footImage, {tintColor: tintColor}]}
			/>
		)
	}},
	Usshow: {screen: usshow, navigationOptions: {
		tabBarLabel: '北美',
		tabBarIcon: ({ tintColor, focused }) => (
				<Image style={[style.footImage, {tintColor: tintColor}]} 
					resizeMode='contain' 
					source={require('../icon/icon_us_normal.png')}
				/>
		)
	}},
	Soonshow: {screen: soonshow, navigationOptions: {
		tabBarLabel: '近期',
		tabBarIcon: ({ tintColor, focused }) => (
				<Image style={[style.footImage, {tintColor: tintColor}]} 
					resizeMode='contain' 
					source={require('../icon/icon_soon_normal.png')}
				/>
		)}
	},
	Nearcinemas: {screen: nearcinemas, navigationOptions: {
		tabBarLabel: '影院',
		tabBarIcon: ({ tintColor, focused }) => (
				<Image style={[style.footImage, {tintColor: tintColor}]} 
					resizeMode='contain' 
					source={require('../icon/icon_near_normal.png')}
				/>
		)},
	}
}, {
	tabBarPosition: 'bottom',
	lazy: true, // 是否懒加载
	initialRouteName: 'Hotshow',
	tabBarOptions: {
		showIcon: true,
		pressOpacity: 0.8,
		style: {
			height: 45,
			backgroundColor: '#ffffff',
			zIndex: 0,
			position: 'relative'
    	},
    	labelStyle: {
        	fontSize: 11,
			paddingVertical: 0,
			marginTop: -4
    	},
		iconStyle: {
			marginTop: -3
		},
		tabStyle: {
			backgroundColor: 'rgb(230,69,51)',
		},
	}
});

TabNavigatorConfig更多具体的参数如下

/**
 * Tab Navigator
 */
export interface TabNavigatorConfig {
  tabBarComponent?: React.ReactElement<any>,
  tabBarPosition?: 'top'|'bottom',
  swipeEnabled?: boolean,
  animationEnabled?: boolean,
  lazy?: boolean,
  tabBarOptions?: {
    activeTintColor?: string,
    activeBackgroundColor?: string,
    inactiveTintColor?: string,
    inactiveBackgroundColor?: string,
    showLabel?: boolean,
    style?: ViewStyle,
    labelStyle?: TextStyle,

    // Top
    showIcon?: boolean,
    upperCaseLabel?: boolean,
    pressColor?: string,
    pressOpacity?: number,
    scrollEnabled?: boolean,
    tabStyle?: ViewStyle,
    indicatorStyle?: ViewStyle
  }
  initialRouteName?: string,
  order?: string[],
  paths?: any     // TODO: better def
  backBehavior?: 'initialRoute'|'none'
}
如上都配置好了,就需要在屏幕上显示 ,下面代码作为展示 主要的还是创建了AppWithNavigationState 然后export 出他, 在root下调用

class AppWithNavigationState extends Component {

	render() {
		return(
			<View style={{flex: 1}}>
				{this.props.fetchbool ? <Loading/> : 
					<AppNavigator navigation={
						addNavigationHelpers({dispatch: this.props.navigator, 
							state: this.props.nav})
					}/>
				}
			</View>
		)
	}
}

function mapStateToProeps(state){
	return {
		fetchbool: state.fetchload.data,
		nav: state.nav
	}
};
function macthDispatchToProps(dispatch) {
    return bindActionCreators({
		navigator: navigator,
		initHotshowAction: initHotshow,
		fetchLoading: fetchLoading
	}, dispatch);
}

let style = StyleSheet.create({
	footImage: {
		width: 25,
		height: 25
	},
});


export default connect(mapStateToProeps, macthDispatchToProps)(AppWithNavigationState);

结合了redux , nav就是通过state 传递的,在redux目录下创建了一个navigators/reducer

import { NavigationActions } from 'react-navigation';
import { AppNavigator } from '../../navigators/AppNavigator';

const initialNavState = {
  index: 0,
  routes: [
    {
      key: 'Hotshow',
      routeName:'Hotshow',
    },
    {
      key: 'Usshow',
      routeName:'Usshow',
    },
    {
      key: 'Soonshow',
      routeName:'Soonshow',
    },
    {
      key: 'Nearcinemas',
      routeName:'Nearcinemas',
    },
  ],
};

export const nav = (state = initialNavState, action) => {
  let nextState;
  switch (action.type) {
    case 'Usshow':
      return AppNavigator.router.getStateForAction(
          NavigationActions.navigate({ routeName: 'Usshow' }),
          state
      );
    case 'Soonshow':
      setate.index= 1
      return AppNavigator.router.getStateForAction(
        NavigationActions.navigate({ routeName: 'Soonshow' }),
        state
      );
    case 'Nearcinemas':
      return AppNavigator.router.getStateForAction(
        NavigationActions.navigate({ routeName: 'Nearcinemas' }),
        state
      );
    default:
     //return AppNavigator.router.getStateForAction(action, state) || state;
      // return AppNavigator.router.getStateForAction(
      //   state
      // );
      return AppNavigator.router.getStateForAction(
        NavigationActions.navigate({ routeName: 'Hotshow' }),
        state
      ) || state ;
  }
}



做到此处,是个tab的四个页面切换还是可以的,问题就在与当我切换到下一个页面时,就出现了状况,


在没有做进入下一个页面前,提前ajax请求,当进入了请求,当然能请求成功,但是请求成功后,刚显示的界面会还在显示等待时,尼玛返回上一个界面

这么说有点拗口,不解其意


额,,,, 清洗脱俗,惊鸿一瞥下就给直接返回A了, console.log(this.props.nav)  看看了 输出一次 nav.index = 0 

然后 1 然后 0 ··········就这么又回到原点了,同时在AppWithNavigationState,解决办法想了一个在navigators/reducer里把nav传递的index固定了

export const nav = (state = initialNavState, action) => {
  let nextState;
  switch (action.type) {
    case 'Usshow':
    setate.index= 1
      return AppNavigator.router.getStateForAction(
          NavigationActions.navigate({ routeName: 'Usshow' }),
          state
      );
有次当然可以解决,但是 tab按钮不能点击咯,这真是尴尬的一幕,

当然还有个蛋疼的直接用TabNavigator 在AppWithNavigationState中的render 会运行四次,即第一个界面加载时,

console.log 输出变知道 当然这样也有办法解决,react 的生命周期呀,最前面的两个 实例化 和存在期,就在存在期入手,

shouldComponentUpdate(nextProps, nextState) {
		return **** ? false : true ;
	}
componentWillUpdate(nextProps, nextState) {
		return *** ? false : true;
}
render()就减小了开销

问题是 tab还是不能点击啊!!!!!!!!

谜底是这样  StackNavigator 需要这个!!!!

export const StackNavigator = StackNavigator(
  {  
	Tab:{screen: AppNavigator},  // 就是整个tab切换的 AppNavigator
	Product:{screen: DtlWebView}  
  },  
  {  
    stackConfig:{  
		header: null,
		headerBackTitle:null,  
		headerTintColor:'#333333',  
		showIcon:true,  
		swipeEnabled:false,  
		animationEnabled:false,
		initialRouteName: 'Hotshow'
	},  
    	mode:'card',
	}
);
stackConfig 主要参数

 TabNavigator, StackNavigator配合应用就很好区分开了前者模块页面之间,后者Stack由字面理解就是通过栈的方式进行切换,最新的就压入到栈顶显示

在App 里之前的就改为StackNavigator

class App extends Component {


	render() {
		return (
			
				<Provider store={ store }>
					<StackNavigator />
				</Provider>
		);
	}
}
到此就结束咯




不对之处,敬请更正··········害羞



相关文章
|
前端开发 容器
React Native TabNavigator底部导航
1). Navigation 官方文档 2). 安装 yarn add react-navigation # or with npm # npm install --save react-navigation 3).
1377 0
|
JavaScript Android开发
react-navigation之TabNavigator, StackNavigator使用配合redux
我在react-navigation的组件StackNavigator 和TabNavigator组合使用在加上redux,出现如下问题 there is no route defined ...
1951 0
|
前端开发 安全 JavaScript
【Message 全局提示】基于 React 实现 Message 组件
使用 ReactDOM.createRoot、React.forwardRef、React.useImperativeHandle 实现 Message 组件。使用 Web Crypto API 生成符合密码学要求的安全的随机 ID。
|
存储 前端开发 JavaScript
React 中非受控和受控的组件
React 中非受控和受控的组件
|
前端开发
react笔记之学习之添加card组件
react笔记之学习之添加card组件
121 0
react笔记之学习之添加card组件
|
前端开发
#yyds干货盘点# react笔记之学习之添加card组件
#yyds干货盘点# react笔记之学习之添加card组件
75 0
#yyds干货盘点# react笔记之学习之添加card组件
|
存储 前端开发 JavaScript
#yyds干货盘点# react笔记之学习之类组件
#yyds干货盘点# react笔记之学习之类组件
86 0
|
前端开发
#yyds干货盘点# react笔记之学习之state组件
#yyds干货盘点# react笔记之学习之state组件
76 0
|
前端开发
#yyds干货盘点# react笔记之学习之修改log组件
#yyds干货盘点# react笔记之学习之修改log组件
86 0
#yyds干货盘点# react笔记之学习之修改log组件
|
前端开发
#yyds干货盘点# react笔记之学习之使用组件完成练习
#yyds干货盘点# react笔记之学习之使用组件完成练习
61 0
#yyds干货盘点# react笔记之学习之使用组件完成练习