Как сбросить историю вкладок в вкладках при нажатии вкладки с помощью ReactNavigation 5?

Я использую React Navigation5. У меня есть навигатор вкладок, и я хочу очистить историю вкладок при нажатии вкладки. Например, я нахожусь на вкладке 1 и перехожу на вкладку 2. На вкладке 2 я перехожу

экран1-> экран2-> экран3

Теперь, если я нажму на вкладку, она должна перейти на начальный экран (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. Когда я возвращаюсь на старую вкладку, история не сбрасывается и на этой вкладке.

любой может мне в этом помочь, спасибо.




Ответы (3)


если вы работаете с вкладками, а затем хотите сбросить вкладку, попробуйте эту React Navigation 5, вот ссылка см. документацию 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" />,
}}

/>

person Zohaib Ahmad    schedule 09.09.2020

вы можете попробовать этот порп: unmountOnBlur

когда вы переходите из ProductsStack в MenuStack, ProductsStack отключается,

ссылка находится здесь

person zks    schedule 24.04.2020

Вот решение с 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' },
          ]
        }
      },
    ]
  })
)

И с этим кодом первая страница, которую вы видите, - это ScreenB экран вкладки tab1_name.

Итак, если вы хотите сначала увидеть экран ScreenF вкладки tab3_name после запуска функции отправки, код должен быть примерно таким:

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' },
          ]
        }
      },
    ]
  })
)

Кстати, когда вы записываете routes вкладки state, он должен следовать последовательности стека страниц. Чтобы все заработало так, как вы ожидали.

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

Если вы опустите первую страницу стека, как указано выше, ScreenE будет недоступен, а будет доступен только ScreenF после запуска функции отправки.

Надеюсь, что это работает для вас.

person Clark    schedule 07.04.2021