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> -
); -
} -
}
到此就结束咯
不对之处,敬请更正··········
转自:https://blog.youkuaiyun.com/ling369523246/article/details/74783288

本文详细介绍如何使用 React Native 的 TabNavigator 和 StackNavigator 实现页面间的切换与导航,并解决了导航过程中遇到的一些具体问题。
751

被折叠的 条评论
为什么被折叠?



