9

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

Eduard
  • 3,395
  • 8
  • 37
  • 62

4 Answers4

11

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

Martin
  • 660
  • 10
  • 23
maqon
  • 166
  • 1
  • 6
2

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)

Shivansh Singh
  • 312
  • 1
  • 2
  • 12
  • 1
    Basically, I want to get rid of the "middle" screen when creating a new conversation, so I can get back from "chat room" to "rooms list" directly, instead of having to get back to "new room" screen. Will give your idea a try. The only wrong thing with my code is this weird animation .. and from what I know, reset has no animation either ? Correct me if I'm wrong. Will give it a try and come back with a reply. – Eduard Sep 28 '17 at 15:03
  • yes reset animation doesn't provide an animation by default unless you choose to implement it. – Shivansh Singh Sep 29 '17 at 07:25
  • 1
    For those arriving here from Google, in v4, you need to use StackActions.reset(). – Jon Edwards Feb 13 '20 at 20:09
0

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,
  }
);
vonovak
  • 1,555
  • 2
  • 14
  • 28
0

If you are using the useNavigate for navigation you can clear the previous route like this :

const navigate = useNavigate();

navigate("/chats",{replace: true,});

Use this replace true to clear the previous route.