95

我遇到了React Navigation和 React Native 的导航问题。这是关于重置导航并返回主屏幕。

我在 DrawerNavigator 中构建了一个 StackNavigator,并且主屏幕和其他屏幕之间的导航正常工作。但问题是,导航堆栈不断增长。我不确定如何从堆栈中删除屏幕。

例如,当从主屏幕进入设置屏幕,然后进入输入屏幕,最后再次进入主屏幕时,主屏幕在堆栈中出现两次。使用后退按钮,我不会退出应用程序,而是再次进入进入屏幕。

再次选择主页按钮时,重置堆栈会很棒,但我不知道该怎么做。在这里,有人试图帮助有类似问题的其他人,但该解决方案对我不起作用。

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

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

这是抽屉屏幕的一个简单示例

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>
  }
}

我希望你能帮助我。这是导航的重要组成部分,一个解决方案会很棒!

4

15 回答 15

79

反应导航 5.x , 6.x

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

navigation.dispatch(
  CommonActions.reset({
    index: 1,
    routes: [
      { name: 'Home' },
      {
        name: 'Profile',
        params: { user: 'jane' },
      },
    ],
  })
);

可用于零食

于 2020-02-12T14:39:34.567 回答
74

这就是我的做法:

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

至少将“菜单”替换为“主页”。您可能还想使 this.props.navigation 适应您的实现。

在版本 > 2 中,请遵循以下内容:

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

this.props.navigation.dispatch(resetAction); 
于 2017-03-30T14:49:05.800 回答
30

我在使用@react-navigation Bashirpour's Answer时发现了这种方法。但是,在尝试已经有导航功能的功能组件时,props这是编写重置堆栈操作的一种巧妙方法:

props.navigation.reset({
     index: 0,
     routes: [{ name: 'Dashboard' }]
})
于 2020-06-20T13:13:40.333 回答
26

这是我的做法:

import { NavigationActions } from 'react-navigation'

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

重要的部分是key: null

这会在从子导航器导航到父导航器时擦除堆栈。

如果您收到此错误,请执行此操作:

在此处输入图像描述

对于动画,我使用

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

我只是自己控制所有的动画。通过用. _<Animatable.View>

于 2017-10-30T20:39:45.263 回答
19

对于最新版本的 react-navigation,您应该使用 StackActions 来重置堆栈,这是一段代码:

// 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...' },
       }),
     ],
   }))
}
于 2018-07-26T18:47:01.053 回答
5

在 React 导航版本 5.x 中

你可以StackActions.replace在这个版本中使用

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


navigation.dispatch(
    StackActions.replace('Home', { test: 'Test Params' })
)

‌</p>

完整示例:(可在Snack中获得)

import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, StackActions } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function SplashScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text style={{fontSize:25,marginBottom:25}} >SPLASH SCREEN!</Text>
      <Button
        title="Replace (RESET) with Home"
        onPress={() =>
          navigation.dispatch(
            StackActions.replace('Home', { test: 'Test Params' })
          )
        }
      />
      <View style={{margin:10}}/>
      <Button
        title="Push Home on the stack"
        onPress={() =>
          navigation.dispatch(StackActions.push('Home', { test: 'Test Params' }))
        }
      />
    </View>
  );
}

function HomeScreen({ navigation, route }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text style={{fontSize:25,marginBottom:25}}>Home Screen!</Text>

      <Text style={{margin:10}}>{route.params.test}</Text>

      <Button
        title="Push same screen on the stack"
        onPress={() => navigation.dispatch(StackActions.pop(1))} 
      /> 
      <View style={{margin:10}}/>
      <Button
        title="Pop one screen from stack" 
        onPress={() =>
          navigation.dispatch(StackActions.push('Home', { test: 'Test Params' }))
        }
      />
      <View style={{margin:10}}/>
      <Button
        title="Pop to top" 
        onPress={() => navigation.dispatch(StackActions.popToTop())}
      />
    </View>
  );
}

const Stack = createStackNavigator();

export default function App() { 
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Splash" component={SplashScreen} />
        <Stack.Screen name="Home" component={HomeScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

于 2020-02-12T12:35:08.413 回答
3

要使用 Back,您需要找到与路径关联的唯一键。在导航减速器中,您可以搜索现有状态以使用该路径查找堆栈上的第一条路由,获取其键并将其传递给 Back。然后返回将导航到您提供的路径之前的屏幕。

  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 );
于 2017-04-26T07:31:39.947 回答
2

NavigationActions.reset()似乎是更好的解决方案。我遇到的一个问题是选项卡按钮。即使我在组件中明确关闭它们,选项卡仍会显示。如果我使用 navigation.navigate() 而不是通过它执行此操作,reset()它会正常工作。

SomeComponentScreen.navigationOptions = {
  header: null
};

对我有用的这种烦恼的解决方法是连续调用多个navigate语句。

      navigation.goBack();   // this would pop current item in stack
      navigation.navigate({
        routeName: 'SomeOtherComponent'
      });
于 2020-04-27T18:43:05.023 回答
1

到目前为止,这可以正常工作:

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

resetStack = () => {
        const navigateAction = NavigationActions.navigate({
            routeName: 'Home',

            params: {},

            action: NavigationActions.navigate({ routeName: 'Home' }),
        });

        props.navigation.dispatch(navigateAction);
    }

在文档中找到:https ://reactnavigation.org/docs/en/navigation-actions.html#reset

于 2019-12-18T07:21:20.760 回答
1

答案是createSwitchNavigator,它不会叠加您的导航。在带有主屏幕/堆栈的 createSwitchNavigator 中添加您的身份验证屏幕/导航器。

这样,当您从家导航登录时,不会保留堆栈。

有关它的更多信息 https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack

于 2018-07-19T09:42:42.263 回答
1

只需混合上面给出的两种解决方案就可以了,基本上我们必须使用 StackActions 和 key: null。不使用 StackActions,它会抛出一些错误

import { NavigationActions, StackActions } from 'react-navigation';
const resetHandler = () => {
        props.navigation.dispatch(StackActions.reset({
            index: 0,
            key: null,
            actions: [NavigationActions.navigate({ routeName: 'PatientDetails' })]
        }))
    };
于 2019-11-13T03:24:36.083 回答
1

pop 操作将您带回到堆栈中的上一个屏幕。n 参数允许您指定要弹出多少个屏幕。

n - number - 要弹回的屏幕数。

从“反应导航”导入 { StackActions };

常量 popAction = StackActions.pop({ n: 1, });

this.props.navigation.dispatch(popAction);

于 2018-07-30T10:12:23.867 回答
0

反应导航 6.x

您可以使用popToTop()操作来重置您的堆栈。例子:

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

navigation.dispatch(StackActions.popToTop());

反应导航文档:https ://reactnavigation.org/docs/stack-actions/#poptotop

于 2021-10-04T07:48:58.150 回答
0

这为我解决了这个问题(React Navigation 5.x

import {NavigationActions} from 'react-navigation';

navigation.reset(
  [NavigationActions.navigate({routeName: 'Profile'})],
  0,
);
于 2021-10-04T17:52:51.197 回答
0

在您的 StackNavigator 和 DrawerNavigator 中,您使用 Home 作为键,我认为它必须是唯一的,这就是它产生问题的原因。您能否尝试在 DrawerNavigator 中将 Home 替换为 Stack。

希望这会有所帮助:)

于 2017-03-29T13:39:10.410 回答