Resetting the navigation stack for the home screen

2020-01-30 05:24发布

I've got a problem with the navigation of React Navigation and React Native. It is about resetting navigation and returning to the home screen.

I've build a StackNavigator inside of a DrawerNavigator, and the navigation between home screen and other screens is working. But the problem is, that the navigation stack grows and grows. I'm not sure how to remove a screen from the stack.

For example when going from the home screen to the settings screen, then to the entry screen and lastly again to the home screen, the home screen is twice in the stack. With the back button I do not get out of the app, but again to the entry screen.

When selecting the home button again a reset of the stack would be great, but I don't know how to do this. Here someone tried to help an other person with a similar problem, but the solution didn't work for me.

const Stack = StackNavigator({
  Home: {
    screen: Home
  },
  Entry: {
    screen: Entry
  },
  Settings: {
    screen: Settings
  }
})

export const Drawer = DrawerNavigator({
  Home: {
    screen: Stack
  }},
  {
    contentComponent: HamburgerMenu
  }
)

And this is a simple example of the drawer screen

export default class HamburgerMenu extends Component {
  render () {
    return <ScrollView>
      <Icon.Button
        name={'home'}
        borderRadius={0}
        size={25}
        onPress={() => { this.props.navigation.navigate('Home')}}>
        <Text>{I18n.t('home')}</Text>
      </Icon.Button>

      <Icon.Button
        name={'settings'}
        borderRadius={0}
        size={25}
        onPress={() => { this.props.navigation.navigate('Settings')}}>
        <Text>{I18n.t('settings')}</Text>
      </Icon.Button>

      <Icon.Button
        name={'entry'}
        borderRadius={0}
        size={25}
        onPress={() => { this.props.navigation.navigate('Entry')}}>
        <Text>{I18n.t('entry')}</Text>
      </Icon.Button>
    </ScrollView>
  }
}

I hope you can help me. This is an essential part of the navigation and a solution would be great!

9条回答
迷人小祖宗
2楼-- · 2020-01-30 05:25

Here is how I do it:

import { NavigationActions } from 'react-navigation'

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

The important part is key: null.

That wipes the stack while navigating from a child navigator to a parent navigator.

Do that if you get this error:

enter image description here

For animations, I use

// https://github.com/oblador/react-native-animatable
import * as Animatable from 'react-native-animatable'

I just control all the animations myself. Put them on any component you want by wrapping it with <Animatable.View>.

查看更多
▲ chillily
3楼-- · 2020-01-30 05:25

The Answer is createSwitchNavigator, it those not stack up your navigation. Add your auth screen/navigator in a createSwitchNavigator with the home screen/stack.

With that, when you navigate from home to log in, the stacks are not kept.

For more on it https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack

查看更多
来,给爷笑一个
4楼-- · 2020-01-30 05:28

Just mix the two solutions given above and this will work just fine, basically we have to use StackActions and key: null. Without using StackActions, it was throwing some error

import { NavigationActions, StackActions } from 'react-navigation';
const resetHandler = () => {
        props.navigation.dispatch(StackActions.reset({
            index: 0,
            key: null,
            actions: [NavigationActions.navigate({ routeName: 'PatientDetails' })]
        }))
    };
查看更多
Emotional °昔
5楼-- · 2020-01-30 05:34

This is How I do it :

reset(){
    return this.props
               .navigation
               .dispatch(NavigationActions.reset(
                 {
                    index: 0,
                    actions: [
                      NavigationActions.navigate({ routeName: 'Menu'})
                    ]
                  }));
  }

at least replace 'Menu' with 'Home'. You may also want to adapt this.props.navigation to your implementation.

In version > 2 follow this:

import { NavigationActions, StackActions } from 'react-navigation';
        const resetAction = StackActions.reset({
                index: 0,
                actions: [NavigationActions.navigate({ routeName: 'MainActivity' })],
            });

this.props.navigation.dispatch(resetAction); 
查看更多
Rolldiameter
6楼-- · 2020-01-30 05:34

To use Back, you need to find the unique key associated with the path. Inside your navigation reducer, you can search the existing state to find the first route on the stack using that path, grab its key & pass that to Back. Back will then navigate to the screen prior to the path you gave.

  let key;

  if (action.payload) {
    // find first key associated with the route
    const route = action.payload;

    const routeObj = state.routes.find( (r) => r.routeName === route );

    if (routeObj) {
      key = { key: routeObj.key };
    }
  }

  return AppNavigator.router.getStateForAction( NavigationActions.back( key ), state );
查看更多
Melony?
7楼-- · 2020-01-30 05:43

For newest versions of react-navigation you should use StackActions for reset the stack, here's a piece of code:

// import the following
import { NavigationActions, StackActions } from 'react-navigation'

// at some point in your code
resetStack = () => {
 this.props
   .navigation
   .dispatch(StackActions.reset({
     index: 0,
     actions: [
       NavigationActions.navigate({
         routeName: 'Home',
         params: { someParams: 'parameters goes here...' },
       }),
     ],
   }))
}
查看更多
登录 后发表回答