当您从另一个选项卡返回选项卡时如何重置选项卡堆栈反应导航v5

问题描述 投票:0回答:5

我有 3 个选项卡,每个选项卡包含一组堆栈导航器。

  1. 主堆栈
    const HomeNavigator = createStackNavigator();

    const HomeStackNavigator = ({navigation, route}) => {
      return (
        <HomeNavigator.Navigator>
          <HomeNavigator.Screen
            name="Home"
            component={Home}
          />
          <HomeNavigator.Screen
            name="Profile"
            component={Profile}
          />
          <HomeNavigator.Screen
            name="Settings"
            component={Settings}
          />
        </HomeNavigator.Navigator>
      );
    };

  1. 存储堆栈

    const StoreNavigator = createStackNavigator();

    const StoreStackNavigator = ({navigation, route}) => {
      return (
        <StoreNavigator.Navigator>
          <StoreNavigator.Screen
            name="OurStore"
            component={Store}
          />
        </StoreNavigator.Navigator>
      );
    };

  1. 社区堆栈
    const CommunityNavigator = createStackNavigator();

    const CommunityStackNavigator = ({navigation, route}) => {
      return (
        <CommunityNavigator.Navigator>
          <CommunityNavigator.Screen
            name="Community"
            component={Community}
          />
          <CommunityNavigator.Screen
            name="CommunityReply"
            component={CommunityReply}
            options={communityReplyOptions}
          />
          <CommunityNavigator.Screen
            name="AskCommunity"
            component={AskCommunity}
          />
        </CommunityNavigator.Navigator>
      );
    };

选项卡导航器


    const MainNavigator = createBottomTabNavigator();

    const MainTabNavigator = () => {
      return (
        <MainNavigator.Navigator
          screenOptions={tabScreenOptions}
          tabBarOptions={tabBarOptions}>
          <MainNavigator.Screen
            name="HomeTab"
            component={HomeStackNavigator}
            options={{tabBarLabel: 'Home'}}
          />
          <MainNavigator.Screen
            name="StoreTab"
            component={StoreStackNavigator}
            options={{tabBarLabel: 'Store'}}
          />
          <MainNavigator.Screen
            name="CommunityTab"
            component={CommunityStackNavigator}
            options={{tabBarLabel: 'Community'}}
          />
        </MainNavigator.Navigator>
      );
    };

我通过使用以下方法单击按钮导航到 HomeTab 中 CommunityTab 选项卡内的 CommunityReply 屏幕

props.navigation.navigate('CommunityTab', { screen: '社区回复', 参数: {postId: postId}, });

工作正常,当我再次返回 CommunityTab 时,它将始终位于 CommunityReply 屏幕中。返回 CommunityTab 选项卡时如何重置选项卡堆栈

React 导航版本

“@react-navigation/bottom-tabs”:“^5.8.0”

“@react-navigation/native”:“^5.7.3”

“@react-navigation/stack”:“^5.9.0”

react-native react-navigation react-navigation-stack react-navigation-bottom-tab
5个回答
26
投票

有一个名为 unmountOnBlur 的属性就是为此目的而设计的。

https://reactnavigation.org/docs/bottom-tab-navigator#unmountonblur

Tab Navigator 中进行的更改:

const MainNavigator = createBottomTabNavigator();

const MainTabNavigator = () => {
  return (
    <MainNavigator.Navigator
-     screenOptions={tabScreenOptions}
+     screenOptions={{...tabScreenOptions, unmountOnBlur: true }}
      tabBarOptions={tabBarOptions}>
      <MainNavigator.Screen
        name="HomeTab"
        component={HomeStackNavigator}
        options={{tabBarLabel: 'Home'}}
      />
      <MainNavigator.Screen
        name="StoreTab"
        component={StoreStackNavigator}
        options={{tabBarLabel: 'Store'}}
      />
      <MainNavigator.Screen
        name="CommunityTab"
        component={CommunityStackNavigator}
        options={{tabBarLabel: 'Community'}}
      />
    </MainNavigator.Navigator>
  );
};

总结:

unmountOnBlur: true
将解决提到的问题。


5
投票

如果您不希望在导航回

CommunityReply
时显示
CommunityTab
屏幕,您需要在
initial
函数中添加
navigate
选项。

props.navigation.navigate(
  'CommunityTab', 
  { 
    screen: 'CommunityReply', 
    initial: false, 
    params: { postId: postId }, 
  }
);

已在文档中解释


4
投票

我为 Jeison Guimarães 解决方案(反应导航 6)制定了更通用的方法。当选项卡索引更改时,此方法会重置选项卡内的任何堆栈导航。这也确保了显示弹出窗口时活动堆栈不会重置。

<Tab.Screen
  name="My tab"
  listeners={resetTabStacksOnBlur}
/>
/**
 * Resets tabs with stackNavigators to the first route when navigation to another tab
 */
const resetTabStacksOnBlur = ({navigation}) => ({
  blur: () => {
    const state = navigation.getState();

    state.routes.forEach((route, tabIndex) => {
      if (state?.index !== tabIndex && route.state?.index > 0) {
        navigation.dispatch(StackActions.popToTop());
      }
    });
  },
});

1
投票

如果上述解决方案不适合您,请尝试此解决方案,它对我有用。

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

<Tab.Screen listeners={({navigation,route})=>({
    blur:()=>{
      navigation.dispatch(
        CommonActions.reset({
          index:4,
          routes:[{name:'Profile'}]
        })
      )
    },
  })} name="Profile"/>

0
投票

对于后代,如果您想避免

unmountOnBlur
,您还可以使用
tabPress
事件(请参阅 docs)。

上面链接中的文档很好地概述了默认选项卡按下行为以及如何修改它。 您还可以查看这个方便的Expo Snack demo

特别是,要导航到选项卡上的初始路线,请按:

function SomeScreen({ navigation }) {

  useEffect(() => {
    const unsubscribe = navigation.addListener('tabPress', e => {
      e.preventDefault();
      navigation.navigate('initialRouteName');
    });

    return unsubscribe;
  }, [ navigation ]);

}

请记住,如果

SomeScreen
位于另一个(嵌套)导航器内,则在添加事件侦听器 (
navigation
) 时,需要从父导航器访问
navigation.getParent().addListener()
属性。

© www.soinside.com 2019 - 2024. All rights reserved.