react-navigation Modal弹出层中的StackNavigator导航如何和物理返回匹配?
带有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: "" }) ) } }} #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'})], }) ) }