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: ""
                            })
                        )
                    }
                }}
                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'})],
        })
  )
}

 

猜你喜欢

转载自www.cnblogs.com/nangezi/p/12346372.html