简体   繁体   English

将屏幕重置为第一个父屏幕,从嵌套屏幕(React 导航和 React Native)

[英]Resetting screen to first Parent screen, from a nested screen (React navigation & React Native)

I've followed the documentation for creating bottom tab navigation with react-navigation v5 ("@react-navigation/native": "^5.2.3")我已经按照文档使用 react-navigation v5 ("@react-navigation/native": "^5.2.3") 创建底部标签导航

Currently is partially used this example in my project from docs https://reactnavigation.org/docs/bottom-tab-navigator/ to fit the needs of version 5.目前在我的文档https://reactnavigation.org/docs/bottom-tab-navigator/的项目中部分使用了此示例,以满足版本 5 的需求。

Example might be following示例可能如下

// Navigation.tsx // 导航.tsx

import { BottomTabBarProps } from '@react-navigation/bottom-tabs';
import { TabActions } from '@react-navigation/native';
import * as React from 'react';

function Navigation({ state, descriptors, navigation }: BottomTabBarProps) {

  return (
    <View>
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const isFocused = state.index === index;
        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true,
          });

          if (!isFocused && !event.defaultPrevented) {
            const jumpToAction = TabActions.jumpTo(options.title || 'Home');
            navigation.dispatch(jumpToAction);
          }
        };

        return (
          <TouchableOpacity
            key={options.title}
            accessibilityLabel={options.tabBarAccessibilityLabel}
            accessibilityRole="button"
            active={isFocused}
            activeOpacity={1}
            testID={options.tabBarTestID}
            onPress={onPress}
          >
            {route.name}
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

export default Navigation;

However, I have a couple of nested StackNavigators as described in AppNavigator.tsx但是,我有几个嵌套的 StackNavigators,如 AppNavigator.tsx 中所述

AppNavigator.tsx应用导航器.tsx

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import React from 'react';
import { AppState, AppStateStatus } from 'react-native';

import Navigation from '../components/navigation/Navigation';
import AccountScreen from '../screens/account';
import SettingsScreen from '../screens/settings';
import SupportScreen from '../screens/support';

import HomeNavigator from './HomeNavigator';
import TransactionNavigator from './TransactionNavigator';

const { Navigator, Screen } = createBottomTabNavigator();

const AppNavigator = () => {

  return (
    <View>
      <Navigator tabBar={(props) => <Navigation {...props} />}>
        <Screen
          component={HomeNavigator}
          name="Home"
          options={{ title: 'Home' }}
        />
        <Screen
          component={TransactionNavigator}
          name="Transactions"
          options={{
            title: 'Transactions' }}
        />
        <Screen
          component={AccountScreen}
          name="Account"
          options={{ title: 'Account' }}
        />
        <Screen
          component={SupportScreen}
          name="Support"
          options={{ title: 'Support' }}
        />
        <Screen
          component={SettingsScreen}
          name="Settings"
          options={{
            title: 'Settings' }}
        />
      </Navigator>
    </View>
  );
};

export default AppNavigator;

And I am aiming for resetting the nested StackNavigator each time user leaves it.我的目标是在每次用户离开时重置嵌套的 StackNavigator。 So example can be HOME -> TRANSACTIONS -> TRANSACTION_DETAIL (which is part of a nested navigator) -> HOME -> TRANSACTIONS因此示例可以是 HOME -> TRANSACTIONS -> TRANSACTION_DETAIL (这是嵌套导航器的一部分)-> HOME -> TRANSACTIONS

currently, I see a TRANSACTION_DETAIL after the last step of the "walk through" path.目前,我在“遍历”路径的最后一步之后看到了 TRANSACTION_DETAIL。 Nevertheless, I want to see TRANSACTIONS instead.不过,我想改为查看 TRANSACTIONS。 I found that if I change我发现如果我改变

if (!isFocused && !event.defaultPrevented) {
  const jumpToAction = TabActions.jumpTo(options.title || 'Home');
  navigation.dispatch(jumpToAction);
}

to

if (!isFocused && !event.defaultPrevented) {
  navigation.reset({ index, routes: [{ name: route.name }] });
}

it more or less does the thing.它或多或少地做了这件事。 But it resets the navigation, so it is unmounted and on return back, all data are lost and need to refetch.但是它重置了导航,所以它被卸载并返回时,所有数据都丢失了,需要重新获取。

In navigation is PopToTop() function that is not available in this scope.在导航中是PopToTop() function 在此 scope 中不可用。

Also I tried to access all nested navigators through descriptors , yet I have not found how to correctly force them to popToTop.我还尝试通过descriptors访问所有嵌套导航器,但我还没有找到如何正确强制它们到 popToTop。

And the idea is do it on one place so it will be handled automatically and there would not be any need to implement it on each screen.这个想法是在一个地方做,所以它会自动处理,不需要在每个屏幕上实现它。

I have tried with navigator.popToTop() but it was not working.我曾尝试使用 navigator.popToTop() 但它不起作用。 It may be stackNavigator and TabNavigator having a different history with the routes.它可能是 stackNavigator 和 TabNavigator 与路线具有不同的历史记录。 I have fixed the issue with the below code.我已经用下面的代码解决了这个问题。 "Home" is my stack navigator name and another "Home" is screen name (Both are same for me) “主页”是我的堆栈导航器名称,另一个“主页”是屏幕名称(两者对我来说都是一样的)

tabBarButton: props => (
        <TouchableOpacity
          {...props}
          onPress={props => {
            navigation.navigate('Home', {
              screen: 'Home'
            })
          }}
        />
      ),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM