aschmid00
aschmid00

Reputation: 7158

Navigate to parent of parent stack

I have this scenario where i have a StackNavigator nested in a TabNavigator nested in another StackNavigator.

const TabOneStack = StackNavigator({
  ScreenA: { screen: ScreenA },
  ScreenB: { screen: ScreenB }
});

const MainTabs = TabNavigator({
  TabOne: { screen: TabOneStack },
  TabTwo: { screen: TabTwoStack }
});

const Root = StackNavigator({
  HomeScreen: { screen: HomeScreen },
  MainTabs: { screen: MainTabs }
});

Everything works but i cant figure out how to navigate for example from ScreenA back to the Home screen in the root StackNavigator. After the HomeScreen the User navigates directly to ScreenA. The back button in the header in ScreenA works fine and brings me back to Home but need a way to have a button that brings me back to the HomeScreen. this.props.navigation.goBack() does not work unfortunately.

i also tried

const backAction = NavigationActions.reset({
  index: 0,
  key: null,
  actions: [
    NavigationActions.navigate({ routeName: 'HomeScreen'})
  ]
});    
this.props.navigation.dispatch(backAction));

but i get:

There is no route defined for key HomeScreen. Must be one of: 'ScreenA', 'ScreenB'.

What is the correct way to do this?

Upvotes: 4

Views: 4152

Answers (5)

fsanaulla
fsanaulla

Reputation: 51

In v6 you can use something like this:

navigation.getParent()?.navigate('Home')

Upvotes: 1

Sophie Cooperman
Sophie Cooperman

Reputation: 524

In the new react native version we use 'StackActions' for this case: StackActions reference

the 'key' parameter in this case is the key to solve this problem. Usually we manage the stack like this:

const resetAction = StackActions.reset({
  index: 0,
  actions: [NavigationActions.navigate({ routeName: 'ScreenA' })],
});

this.props.navigation.dispatch(resetAction);

but StackActions object has another option and its: 'key' - its an optional string or null - If set, the navigator with the given key will reset. If null, the root navigator will reset.

So in this case, to reset back to root and navigate to some screen inside it -> in your case from 'ScreenA' to 'HomeScreen' - you should write:

this.props.navigation.dispatch(
        StackActions.reset({
          index: 0,
          key:null,
          actions: [
            NavigationActions.navigate({
              routeName: 'HomeScreen'
            })
          ]
        })
      );

Notice, in this new version we no longer use 'NavigationActions' to reset the stack, only 'StackActions'.

Upvotes: 3

Val
Val

Reputation: 22807

To traverse from child StackNavigator back to parent StackNavigator, do:

class ScreenA extends Component {
    render() {
        return (<Button onPress={() => {
            this.props.navigation.dispatch({type: 'Navigation/BACK'});
        }} title='ScreenA. back to Home' />);
    }
}

this.props.navigation.dispatch() with 'Navigation/BACK' works exactly the same as the top-most back button.
It differs from goBack() by apply parent-child stack traversing, while goBack() does not.

Result:

enter image description here

And note @Jigar's answer is also correct, it's just a shorthand notation of mine. The key is to pass null argument into goBack(). It won't work without that.

this.props.navigation.goBack(null);

Upvotes: 3

Jigar
Jigar

Reputation: 1374

use this

this.props.navigation.goBack(null);

Upvotes: 1

DennisFrea
DennisFrea

Reputation: 1122

For me, it's should working fine by using this:

Change this:

this.props.navigation.dispatch(backAction));

to

this.navigator.dispatch(backAction);

Also in your render

  render() {
    return (
      <Root
        ref={(nav) => {
          this.navigator = nav;
        }}
      />
    );
  }

Upvotes: 0

Related Questions