首页 > 解决方案 > 如何导航到堆栈顶部(在 react-navigation-v5/6 上)?

问题描述

使用 React-Navigation v5/6,我想导航到堆栈的第一个屏幕(而不是最后一个屏幕,我最后一次访问这个堆栈。)?

我尝试使用dispatch(StackActions.popToTop()). 但是,如果用户已经在堆栈顶部,则会导致错误!

错误是:The action 'POP_TO_TOP' was not handled by any navigator. Is there any screen to go back to? This is a development-only warning and won't be shown in production.

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

props.navigation.navigate("MyStack");

// The following works most of the time. However, it causes an error if the user is already on top of the stack! 
props.navigation.dispatch(StackActions.popToTop()); 

标签: react-nativereact-navigationreact-navigation-v5react-navigation-stackreact-navigation-v6

解决方案


以下代码似乎有效。但是,对于这样一个基本(我认为)要求,这是一个相当长的代码。我想知道是否有更简单的解决方案。

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

props.navigation.dispatch(state => {
    // 1. Find (by name) the stack, which needs to be reset 
    let i; 
    for (i = 0; i < state.routes.length; i++) {
        if (state.routes[i].name === "MyStack") {
            break;
        }
    }

    // 2. If there has been any activity for the stack, which we found above, we reset it 
    let routes2 = { ...state.routes };
    if (routes2[i].state) { 
        delete routes2[i].state;
    }

    // 3. Update state
    return CommonActions.reset({
        ...state,
        routes2,
    });
});

// 4. navigate to the stack (after it has been reset)
props.navigation.navigate("MyStack");

要重置抽屉堆栈:

import { CommonActions } from "@react-navigation/native";
// ...........
<MyNav.Navigator 
    screenListeners={({ navigation, route }) => ({ 
        focus: (e) => { 
            navigation.dispatch(state => {
                // 1. Find the stack, which needs to be reset -> Get "i"
                let i; 
                for (i = 0; i < state.routes.length; i++) {
                    if (state.routes[i].name === route.name) {
                        break;
                    }
                }
                
                // 2. If there has been any activity for the stack, which we found above (having "i"), we reset it 
                let routes2 = { ...state.routes };
                if (routes2[i].state) { 
                    delete routes2[i].state;
                }
                
                // 3. Update the "state"
                return CommonActions.reset({
                    ...state,
                    routes2,
                });
            });

            // 4. navigate to the stack (after it has been reset)
            navigation.navigate(route.name);                                  
        } 
    })}
>
// ...........
</MyNav.Navigator>

推荐阅读