带有StackNavigator的Modal弹出层
const StackReouteConfig = {
Login: {
screen: Login
},
Register: {
screen: Register
},
ForgetPassword: {
screen: ForgetPassword
}
}
const StackNavigatorConfigs = {
initialRouteName: "Login",
headerMode: "screen",
mode: "modal",
navigationOptions: {
headerStyle: {
}
}
}
const StackNavigator = createStackNavigator(StackReouteConfig, StackNavigatorConfigs);
const UserModalNavigator = createAppContainer(StackNavigator);
// 重写getStateForAction,防止重复跳转
const navigateOnce = (getStateForAction) => (action, state) => {
const {type, routeName, params} = action;
return (
state &&
(type === NavigationActions.NAVIGATE) &&
routeName === state.routes[state.routes.length - 1].routeName &&
JSON.stringify(params) === JSON.stringify(state.routes[state.routes.length - 1].params)
) ? null getStateForAction(action, state);
};
UserModalNavigator.router.getStateForAction = navigateOnce(UserModalNavigator.router.getStateForAction);
// 带有StackNavigator的弹出层
export default UserModal extends Component {
constructor(props) {
super(props);
this.state = {
visible: true //可以props传递
}
}
render() {
return (
<Modal
animationType={"slide"}
transparent={false}
visible={this.state.visible}
onRequestClose={() => {
// 判断是否是第一个
if(this._navigator.state.nav.index === 0) {
// 隐藏此Modal
} else {
// 返回上一页,栈回退
this._navigator.dispatch(
NavigationActions.back({
type: NavigationActions.BACK,
key: ""
})
)
}
}}
style={{backgroundColor: "#fff"}}>
<UserModalNavigator
ref={navigationRef => this._navigator = navigationRef}/>
</Modal>
)
}
}
几点说明:
this._navigator 是 UserModalNavigator组件,也就是 createAppContainer 方法返回的对象
createAppContainer 返回的对象 NavigationContainer 含有 router、screenProps、navigationOptions、state等属性
想要在没有navigation的情况下使用navigation:
1. 可以使用 withNavigation方法包裹组件,从而使得组件 能够使用 navigation的属性和方法
2. 使用 NavigationContainer 对象来重写navigation的方法,从而达到使用navigation的效果
如上面的代码:重写goBack()方法
this._navigator.dispatch(
NavigationActions.back({
type: NavigationActions.BACK,
key: ""
})
)
还有类似的
//重写navigate 方法
function navigate(routeName, params) {
_navigator && _navigator.dispatch(
NavigationActions.navigate({
type: NavigationActions.NAVIGATE,
routeName,
params
})
)
}
//重写reset方法
function reset(routeName, params) {
_navigator && _navigator.dispatch(
StackAction.reset({
index: 0,
actions: [NAvigationActions.navigate({ routeName: 'HomeScreen'})],
})
)
}