【问题标题】:How reset tab history in Tabs on tab click using ReactNavigation 5?如何使用 ReactNavigation 5 在选项卡单击时重置选项卡历史记录?
【发布时间】:2020-04-07 05:48:18
【问题描述】:

我正在使用 React Navigation5。 我有一个选项卡导航器,想清除单击选项卡上的选项卡历史记录。 例如,我在选项卡 1 上,然后转到选项卡 2。 从tab2,我导航

screen1->screen2->screen3

现在,如果我单击选项卡,它应该会进入初始屏幕 (screen1)。 但它不起作用,它以错误的方式工作。 这是我的代码。

import React from 'react';

import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { CommonActions, StackActions } from '@react-navigation/native';


// Custom imports:
import StartScreen from '../screens/start/StartScreen';
import ProductsScreen from '../screens/products/ProductsScreen';
import AddCustomerScreen from '../screens/customers/AddCustomerScreen';
import CustomersScreen from '../screens/customers/CustomersScreen';
import WebviewScreen from '../screens/webview/WebviewScreen';

// Menu Screen
import MenuScreen from '../screens/menu/MenuScreen';
import CurrentAccountScreen from '../screens/menu/CurrentAccountScreen';
import AccountDetailScreen from '../screens/menu/AccountDetailScreen';
import AppInfoScreen from '../screens/menu/AppInfoScreen';
import MessagesScreen from '../screens/menu/MessagesScreen';

import { Colors, GlobalStyles } from '../constants';

import { Badge, CustomIcon } from '../components/icons';
import {
  iconStart,
  iconProducts,
  iconCustomers,
  iconMenu
} from '../components/icons/TabBarIcons';
import {
  IconLowbarAddOrder,
} from '../components/IconFiles';


const Stack = createStackNavigator();

// Initial Parameters for WebView
let initParamsForWebView = {
  url: '',
  screenName: '',
  haveUser: false,
  user: false
};

/**
* Start Stack Navigator
**/
const INIT_START_ROUTE = 'Start';
function StartStack() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }} initialRouteName={INIT_START_ROUTE}>
      <Stack.Screen name="Start" component={StartScreen} />
      <Stack.Screen name="Webview"
        component={WebviewScreen}
        initialParams={initParamsForWebView}
      />
    </Stack.Navigator>
  );
}


/**
* Products Stack Navigator
**/
const INIT_PRODUCTS_ROUTE = 'Products';
function ProductsStack() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }} initialRouteName={INIT_PRODUCTS_ROUTE}>
      <Stack.Screen name="Products" component={ProductsScreen} />
      <Stack.Screen name="Webview"
        component={WebviewScreen}
        initialParams={initParamsForWebView}
      />
    </Stack.Navigator>
  );
}

/**
* Menu Stack Navigator
**/
const INIT_MENU_ROUTE = 'Menu';
function MenuStack() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }} initialRouteName={INIT_CUSTOMERS_ROUTE}>
      <Stack.Screen name="Menu" component={MenuScreen} />
      <Stack.Screen name="CurrentAccount" component={CurrentAccountScreen} />
      <Stack.Screen name="AccountDetail" component={AccountDetailScreen} />
      <Stack.Screen name="AppInfo" component={AppInfoScreen} />
      <Stack.Screen name="Messages" component={MessagesScreen} />
      <Stack.Screen name="Webview"
        component={WebviewScreen}
        initialParams={initParamsForWebView}
      />
    </Stack.Navigator>
  );
}


function resetStack(navigation, _route, _stack, _screen){
  console.log(_route);
  console.log(navigation);
  console.log('ResetStack Called');
  navigation.dispatch(
            CommonActions.reset({
                index: 0,
                routes: [
                    { name: _stack}
                ]
            })
        );
}

const BottomTab = createBottomTabNavigator();

const INITIAL_ROUTE_NAME = 'StartStack';
export default function ParticipantNavigator({ navigation, route }) {
  // screenOptions={{ headerShown: false }} 
  return (
    <BottomTab.Navigator
      screenOptions={{ headerShown: false }} 
      initialRouteName={INITIAL_ROUTE_NAME}
      lazy='false'
      tabBarOptions={{}}>
      <BottomTab.Screen
        name="StartStack"
        component={StartStack}
        options={{
          title: 'Start'
        }}

        listeners={{
          tabPress: e => {
            resetStack(navigation, route, 'StartStack', INIT_START_ROUTE);
          }
        }}
      />
      <BottomTab.Screen
        name="ProductsStack"
        component={ProductsStack}
        options={{
          title: 'Products'
        }}
        listeners={{
          tabPress: e => {
            resetStack(navigation, route, 'ProductsStack', INIT_PRODUCTS_ROUTE);
          }
        }}
      />

      <BottomTab.Screen
        name="MenuStack"
        component={MenuStack}
        options={{
          title: 'Menu'
        }}
        listeners={{
          tabPress: e => {
            resetStack(navigation, route, 'MenuStack', INIT_MENU_ROUTE);
          }
        }}
      />
    </BottomTab.Navigator>
  );
}

这段代码我面临两个问题。

  1. 当我单击选项卡时,它会转到第一个选项卡,而不是移动到单击选项卡的第一个屏幕。
  2. 当我回到旧标签时,该标签上的历史记录也不会重置。

任何人都可以帮助我,谢谢。

【问题讨论】:

    标签: react-native react-navigation react-navigation-stack react-navigation-v5 react-navigation-bottom-tab


    【解决方案1】:

    如果你在标签上工作,然后想重置标签,那么试试这个 React Navigation 5 这里是链接see the documentation React Navigation 5

    <BottomTab.Screen
    name="Post"
    component={PostStack}
    options={{
      unmountOnBlur: true,// set this props in your tab screen options
      title: 'Post',
      tabBarIcon: focused => <TabBarIcon focused={focused} name="Post" />,
    }}
    

    />

    【讨论】:

      【解决方案2】:

      你可以试试这个porp:unmountOnBlur

      当您从 ProductsStack 到 MenuStack 时,ProductsStack 将卸载,

      链接是here

      【讨论】:

        【解决方案3】:

        这是 React Navigation 5.x 的解决方案

        https://stackoverflow.com/a/66982007/10672805



        下面的代码用于重置多个标签。

        TabNavigator
            Tab1: 'tab1_name' 
              StackNavigator
                 - ScreenA
                 - ScreenB
        
            Tab2: 'tabs_name'
              StackNavigator
                 - ScreenC
                 - ScreenD
        
            Tab3: 'tab3_name'
              StackNavigator
                 - ScreenE
                 - ScreenF
        
        navigation.dispatch(
          CommonActions.reset({
            routes: [
              {
                name: 'tab1_name',
                state: {
                  routes: [
                    { name: 'ScreenA' },
                    { name: 'ScreenB' },
                  ]
                }
              },
              {
                name: 'tab2_name',
                state: {
                  routes: [
                    { name: 'ScreenC' },
                  ]
                }
              },
              {
                name: 'tab3_name',
                state: {
                  routes: [
                    { name: 'ScreenE' },
                    { name: 'ScreenF' },
                  ]
                }
              },
            ]
          })
        )
        

        使用此代码,您看到的第一页是tab1_name 选项卡的ScreenB 屏幕。

        所以,如果你想在运行调度函数后首先看到tab3_name标签的ScreenF屏幕,代码应该是这样的:

        navigation.dispatch(
          CommonActions.reset({
            routes: [
              {
                name: 'tab3_name',
                state: {
                  routes: [
                    { name: 'ScreenE' },
                    { name: 'ScreenF' },
                  ]
                }
              },
              {
                name: 'tab1_name',
                state: {
                  routes: [
                    { name: 'ScreenA' },
                    { name: 'ScreenB' },
                  ]
                }
              },
              {
                name: 'tab2_name',
                state: {
                  routes: [
                    { name: 'ScreenC' },
                  ]
                }
              },
            ]
          })
        )
        

        顺便说一句,当你写下标签的stateroutes 时,它应该遵循页面堆栈的顺序。这样它就可以按您的预期工作。

        navigation.dispatch(
          CommonActions.reset({
            routes: [
              {
                name: 'tab3_name',
                state: {
                  routes: [
                    // { name: 'ScreenE' },   // removed
                    { name: 'ScreenF' },
                  ]
                }
              },
              ...
        

        如果你省略上面的第一个堆栈页面,ScreenE 是不可访问的,而在运行调度函数后只能访问 ScreenF

        希望这对你有用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-31
          • 1970-01-01
          • 1970-01-01
          • 2016-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-09-27
          相关资源
          最近更新 更多