帶有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'})], }) ) }
