You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native登录后在两个Stack Navigator间导航报错求助

问题原因

Login页面属于OutsideStack,这个栈仅包含Login、Register、Forget三个页面,而Home页面在InsideStack中。由于两个栈是通过auth状态互斥渲染的,当前Login页面的导航对象只能访问OutsideStack内的路由,所以直接调用navigation.push("Home")会找不到对应页面,触发报错"Do you have a screen named 'Home'?"。

解决方案

推荐两种可行的解决方式,可根据项目需求选择:

方式一:通过更新auth状态切换栈(简单直接)

利用App.js中auth状态控制栈渲染的逻辑,登录成功后更新状态,自动切换到包含Home的InsideStack。

  1. 修改OutsideStack组件,传递登录成功回调
    给OutsideStack添加onLoginSuccess props,并传递给Login页面:
const OutsideStack = ({ onLoginSuccess }) => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Login"
        screenOptions={{ headerShown: false }}
      >
        {/* 通过回调方式传递props给Login组件 */}
        <Stack.Screen name="Login">
          {(props) => <AuthLogin {...props} onLoginSuccess={onLoginSuccess} />}
        </Stack.Screen>
        <Stack.Screen name="Register" component={AuthRegister} />
        <Stack.Screen name="Forget" component={ForgetPassword} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};
  1. 在App.js中传递状态更新函数
    修改App.js里的栈渲染逻辑,把setAuth作为回调传给OutsideStack:
{auth == "true" ? <InsideStack /> : <OutsideStack onLoginSuccess={() => setAuth("true")} />}
  1. 更新Login页面的登录逻辑
    登录成功后先存储状态,再调用回调更新App的auth状态:
const handleLogin = async () => {
  try {
    await AsyncStorage.setItem("isLoggedin", JSON.stringify(true));
    // 触发App的状态更新,自动切换到InsideStack
    props.onLoginSuccess();
  } catch (e) {
    console.error("存储登录状态失败:", e);
  }
};

方式二:重构为单NavigationContainer的嵌套栈(符合RN导航最佳实践)

React Navigation推荐一个App仅保留一个NavigationContainer,避免多个容器导致的导航上下文冲突。

  1. 创建根栈RootStack
    把InsideStack和OutsideStack作为根栈的两个屏幕,统一用一个NavigationContainer包裹:
const RootStack = () => {
  const [auth, setAuth] = useState(false);

  useEffect(() => {
    (async () => {
      const value = await AsyncStorage.getItem("isLoggedin");
      setAuth(value === "true");
    })();
  }, []);

  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        {auth ? (
          <Stack.Screen name="Inside" component={InsideStack} />
        ) : (
          <Stack.Screen name="Outside" component={OutsideStack} />
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
};
  1. 移除InsideStack和OutsideStack中的NavigationContainer
    两个子栈不再需要独立的容器:
// InsideStack修改后
const InsideStack = () => {
  return (
    <Stack.Navigator
      initialRouteName="Home"
      screenOptions={{ headerShown: false }}
    >
      <Stack.Screen name="Home" component={MainScreen} />
      <Stack.Screen name="Schools" component={SchoolsScreen} />
      <Stack.Screen name="Setting" component={SettingScreen} />
      <Stack.Screen name="Profile" component={ProfileScreen} />
      <Stack.Screen name="Saved" component={SavedData} />
      <Stack.Screen name="Profile2" component={Profile2} />
      <Stack.Screen name="SchoolDetails" component={SchoolDetailsScreen} />
      <Stack.Screen name="Bottom" component={BottomTab} />
    </Stack.Navigator>
  );
};

// OutsideStack修改后
const OutsideStack = () => {
  return (
    <Stack.Navigator
      initialRouteName="Login"
      screenOptions={{ headerShown: false }}
    >
      <Stack.Screen name="Login" component={AuthLogin} />
      <Stack.Screen name="Register" component={AuthRegister} />
      <Stack.Screen name="Forget" component={ForgetPassword} />
    </Stack.Navigator>
  );
};
  1. Login页面中直接导航到Home
    登录成功后,通过嵌套栈的方式导航到InsideStack下的Home页面:
const handleLogin = async () => {
  try {
    await AsyncStorage.setItem("isLoggedin", JSON.stringify(true));
    // 重置导航栈,避免返回登录页
    navigation.reset({
      index: 0,
      routes: [{ name: "Inside", params: { screen: "Home" } }],
    });
    // 也可以用navigate:navigation.navigate("Inside", { screen: "Home" })
  } catch (e) {
    console.error("存储登录状态失败:", e);
  }
};
注意事项
  • 异步操作要加await:原来的代码中storeData()是异步函数,直接调用后立即执行navigation.push会导致状态还没存储完成,必须用await等待存储完成。
  • 状态判断严谨性:AsyncStorage.getItem返回的是字符串,判断登录状态时建议用value === "true"代替value == "true",避免类型隐式转换问题。

内容的提问来源于stack exchange,提问作者MAYANK THAKUR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:01:01