Remove last route from react navigation stack

Viewed 24838

So, I have the following screens:

- ChatList
- NewRoom
- ChatRoom

Basically, I don't want to go back to Start a new chat from the just-created chat room ... but instead go directly into the chat rooms list. So far, I came up with the following:

const prevGetStateForActionChatStack = ChatStack.router.getStateForAction

ChatStack.router.getStateForAction = (action, state) => {
    if (state && action.type === 'RemovePreviousScreen') {
        const routes = state.routes.slice( 0, state.routes.length - 2 ).concat( state.routes.slice( -1 ) )
        return {
            ...state,
            routes,
            index: routes.length - 1
        }
    }
    return prevGetStateForActionChatStack(action, state)
}

And it theoretically works ... but there is a weird animation when removing the previous route after getting to the new room, as follows. Let me know if you guys have any solution to this issue ...

Example

3 Answers

In react-navigation@3.0

import { StackActions, NavigationActions } from 'react-navigation';

const resetAction = StackActions.reset({
    index: 0,
    actions: [NavigationActions.navigate({ routeName: 'Profile' })],
});
this.props.navigation.dispatch(resetAction);

https://reactnavigation.org/docs/en/stack-actions.html#reset

In react-navigation@6.0

The reset action is replaced by replace.

import { StackActions } from '@react-navigation/native';

navigation.dispatch(   
    StackActions.replace('Profile', {user: 'jane',}) 
);

https://reactnavigation.org/docs/stack-actions/#replace

From your code it seems you are using react-navigation.

React-Navigation has a reset action that allows you to set the screen stack. For example: In your case,

Screen 1: Chat room

Screen 2: Chat list

If you want to remove the chatroom screen from your stack you need to write it as

import { NavigationActions } from 'react-navigation'

const resetAction = NavigationActions.reset({
  index: 0,
  actions: [
    NavigationActions.navigate({ routeName: 'chatlist'})
  ]
})
this.props.navigation.dispatch(resetAction)

This will reset your stack to only one screen as initial screen that is chatlist. actions array can have multiple routes and index defines the active route.

For further details refer the following link:

https://reactnavigation.org/docs/navigators/navigation-actions

Resetting the navigation stack for the home screen (React Navigation and React Native)

you should be able to use the following to change the animation:

export const doNotAnimateWhenGoingBack = () => ({
  // NOTE https://github.com/react-community/react-navigation/issues/1865 to avoid back animation
  screenInterpolator: sceneProps => {
    if (Platform.isIos) {
      // on ios the animation actually looks good! :D
      return CardStackStyleInterpolator.forHorizontal(sceneProps);
    }
    if (
      sceneProps.index === 0 &&
      sceneProps.scene.route.routeName !== 'nameOfScreenYouWannaGoTo' &&
      sceneProps.scenes.length > 2
    )
      return null;

    return CardStackStyleInterpolator.forVertical(sceneProps);
  },
});

and use it as follows:

const Stack = StackNavigator(
  {
  ...screens...
  },
  {
    transitionConfig: doNotAnimateWhenGoingBack,
  }
);
Related