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.csdn.net/ling369523246/article/details/74783288