react-native结合react-navigation之TabNavigator

来源:互联网 发布:梅花女子大学 知乎 编辑:程序博客网 时间:2024/05/20 01:33

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

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


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

// 两个参数 routeConfigs: NavigationRouteConfigMap,  config: TabNavigatorConfig = {}// 一个route对应的页面和tab图标, 一个切换的样式整个tab栏的样式//tabexport 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切换的 AppNavigatorProduct:{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>);}}
到此就结束咯




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



阅读全文
0 0