react-native结合react-navigation之TabNavigator

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: '北美',focused }) => (
				<Image style={[style.footimage,{tintColor: tintColor}]} 
					resizeMode='contain' 
					source={require('../icon/icon_us_normal.png')}
				/>
		)
	}},Soonshow: {screen: soonshow,navigationoptions: {
		tabBarLabel: '近期',{tintColor: tintColor}]} 
					resizeMode='contain' 
					source={require('../icon/icon_soon_normal.png')}
				/>
		)}
	},Nearcinemas: {screen: nearcinemas,navigationoptions: {
		tabBarLabel: '影院',{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 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...