Closed barron9 closed 7 years ago
I need this. After Login screen, I sent to Main screen. but customer by mistake press back button and load the Login screen again. very irritating. any solution ?
You can override the getStateForAction
method of the navigator to prevent a user from going back from a screen and/or prevent them from going back to a screen:
const prevGetStateForAction = Navigator.router.getStateForAction;
Navigator.router.getStateForAction = (action, state) => {
// Do not allow to go back from Home
if (action.type === 'Navigation/BACK' && state && state.routes[state.index].routeName === 'Home') {
return null;
}
// Do not allow to go back to Login
if (action.type === 'Navigation/BACK' && state) {
const newRoutes = state.routes.filter(r => r.routeName !== 'Login');
const newIndex = newRoutes.length - 1;
return prevGetStateForAction(action, { index: newIndex, routes: newRoutes });
}
return prevGetStateForAction(action, state);
};
I tried to prevent app close with the backbutton. is it posible too. I tried the implementation but it doesn't work.
@bennygenel This prevents the back button from closing the app in my case. Are you using the current version of react-navigation and using the code snippet I posted?
@barron9 @nsisodiya does something similar to the below solve the problem for you?
export default class Main extends Component {
constructor(){
super();
this.state = {
}
}
static navigationOptions = {
headerLeft: null
}
@nsisodiya did you try to replace the navigation state when moving from login to main screen instead of standard navigation?
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: "MainScreen",
params: { user }
})
]
});
this.props.navigation.dispatch(resetAction);
@Buthrakaur I have a stack navigation with Home, Login, Main(Tab Navigation)
When the user opens the app he sees the Home Screen, from there he taps Login to go to the Login Screen
i added the code you gave in the function after successful authentication in the Login Screen and i see the Home Screen briefly before i get redirected to Main
I have a screen with some data on it, and I want to save the data in draft form when the user taps 'back'.
I found this thread while trying to work out how to implement this and so adding this note here for anyone else in the same position, as it took a while to work out the solution.
I used the Router's https://reactnavigation.org/docs/routers/api#getStateForAction-action-state
const Navigation = StackNavigator({
// screens defined here
})
const prevGetStateForAction = Navigation.router.getStateForAction;
Navigation.router.getStateForAction = (action, state) => {
// don't allow back from 'EditReport'
if (action.type === 'Navigation/BACK' && state && state.routes[state.index].routeName === 'EditReport') {
// additional logic here to save draft data
// used this.props.navigation.setParams in the Screen
// and state.routes[state.index].params here
return state;
}
return prevGetStateForAction(action, state);
};
To prevent Android from exiting the app I also had to add this to MainActivity.java
:
@Override
public void invokeDefaultOnBackPressed() {
//moveTaskToBack(true);
}
function confirmLogoutAlert (logout) {
Alert.alert(
strings.logOutVerb,
strings.confirmLogOut,
[
{text:strings.cancel, onPress:() => console.log('Cancel logout')},
{text:ok, onPress:logout}
]
)
}
function processBackPress () {
const scene = navigate.getCurrentRoute().routeName
switch (scene) {
case LOGIN:
return
case DRAWER:
store.dispatch(actionCreators.setDrawerOpen(false))
return true
case SETTINGS:
confirmLogoutAlert(logout)
return true
}
return navigate.back()
}
BackHandler.addEventListener('hardwareBackPress', processBackPress)
This plus use reset()
instead of navigate()
if you want to disable back from headerLeft on the next route
@matthamil I tried your code but it doesn't work (tested on iOS). Seem like getStateForAction
was called after I swiped Home screen to the left.
@Buthrakaur's solution did the trick
I need this. After Login screen, I sent to Main screen. but customer by mistake press back button and load the Login screen again. very irritating. any solution ?
hey do you solve that problem I'm getting same issue with my app.
I solved this by following:
const defaultGetStateForAction = PrimaryNavigation.router.getStateForAction;
PrimaryNavigation.router.getStateForAction = (action, state) => {
if (Platform.OS === "android") {
const screen = state ? state.routes[state.index] : null;
if (
action.type === NavigationActions.BACK &&
screen &&
(screen.routeName === "Register" ||
screen.routeName === "OwnerDashboard" ||
screen.routeName === "LandingPage" ||
screen.routeName === "OptionPage" ||
(screen.routeName === "loginStack" && screen.index == 0)
|| (screen.routeName === "driverStack" &&
screen.index == 0 &&
screen.routes[screen.index].index == 0 )
|| (
screen.routeName === "ownerStack" &&
screen.index == 0 &&
screen.routes[screen.index].index == 0
)
)
) {
Alert.alert(
"Are you sure",
"You want to exit the App",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "OK", onPress: () =>{ BackHandler.exitApp() }}
],
{ cancelable: false }
);
console.log("action",action,"state",state);
return null;
}
else{
return defaultGetStateForAction(action, state);
}
}
else{
return defaultGetStateForAction(action, state);
}
};
Its working fine to my desire.
@nsisodiya if you are using react native navigator then on login button click just use this code
this.props.navigation.replace('home')
@nsisodiya if you are using react native navigator then on login button click just use this code
this.props.navigation.replace('home')
This will work in case of react-navigation
as well.
@nsisodiya if you are using react native navigator then on login button click just use this code
this.props.navigation.replace('home')
This will not work on react-navigation v5
this.props.navigation.navigate("User")
works
this.props.navigation.replace("User")
cant find screen
@JsonGuy one limitation I found earlier on replace is that it doesn't allow you to switch navigator like navigate does. Not sure if that is your case.
@nsisodiya if you are using react native navigator then on login button click just use this code
this.props.navigation.replace('home')
I have 3 screens, the application will load screen A first time.
this.props.navigation.replace('B')
,this.props.navigation.navigate('C')
this.props.navigation.goBack()
, you will see screen B becomes a blank white screen,How to fix this error?
@nsisodiya if you are using react native navigator then on login button click just use this code
this.props.navigation.replace('home')
This will work in case of
react-navigation
as well.
This is only useful if you don't have screen other than login. If there's an starter screen, user can still navigate back.
If anyone is still looking for a method to do this, you can refer to this part of the docs for react navigation https://reactnavigation.org/docs/navigation-prop/#dispatch
I modified the code just a little, my code goes like this
navigation.dispatch((state) => {
const routes = [ ...state.routes];
return CommonActions.reset({
/* removed the ...state line from here which technically
removes all the history from my navigation state,
but the routes are still available as i have declared the routes array*/
routes,
index: 0, /* set the index value to 0 because my "Home" screen is at 0 index.
So whichever screen you want to go, just specify the index.
You can check your screens index by console.log(state.routes) */
});
});
@nsisodiya si está utilizando el navegador nativo reaccionar, luego haga clic en el botón de inicio de sesión solo use este código
this.props.navigation.replace('home')
navigation.replace('Login') ---> this solution is ok. Redirect the screen and avoid sliding goback on iOS at least
You can use this code:
this.props.navigation.dispatch( CommonActions.reset({ index: 1, routes: [ { name: 'YourDesiredScreen' } ], }) );
Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.
how can I disable back arrow after navigated to another page?