尝试使用 AuthStack 进行用户身份验证时出现错误

问题描述 投票:0回答:1

我是 React Native 的新手,在尝试获取用户令牌以检查用户是否经过身份验证时遇到问题。如果找到令牌,我认为用户已通过身份验证并尝试显示根堆栈。然而,我遇到的问题是 AuthStack 的屏幕仍然安装在 RootStack 的顶部。有人可以帮助我吗

下面是我的代码:

import { router, Slot, Stack, Tabs } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { useContext, useEffect, useState } from "react";
import { AuthContext, AuthContextProvider } from "../context/AuthContext";
import { ActivityIndicator, View } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { getUserInforWithToken } from "../controller/AuthController";
function RootStack() {
  return (
    <Stack>
      <Stack.Screen name="(root)/index" options={{ title: "Welcome" }} />
    </Stack>
  );
}
function AuthStack() {
  return (
    <Stack
      screenOptions={{
        headerStyle: { backgroundColor: "#6779ef" },
        headerTintColor: "white",
        contentStyle: { backgroundColor: "#6779ef" },
        headerShown: false,
      }}>
      <Stack.Screen name="(auth)/index" options={{ title: "Login Page" }} />
      <Stack.Screen name="(auth)/signup" options={{ title: "Sign Up Page" }} />
    </Stack>
  );
}
function Root() {
  const { setIsLogin, setToken, setIsTryingLogin, isTryingLogin } =
    useContext(AuthContext);
  const [isLoading, setIsLoading] = useState(true);
  const { isLogin } = useContext(AuthContext);

  useEffect(() => {
    const checkAuth = async () => {
      const token = await AsyncStorage.getItem("token");
      if (token) {
        console.log("token found, user logged in");
        setIsLogin(true);
        setToken(token);
      } else {
        setIsLogin(false);
      }
      // Set trying login to false after we check for token
      setIsTryingLogin(false);
    };

    checkAuth();
  }, []); // This runs only once on component mount

  useEffect(() => {
    if (!isTryingLogin) {
      setIsLoading(false);
    }
      }, [isTryingLogin]);
      if (isLoading) {
        console.log("Loading...");
        return (
          <View className="flex-1 justify-center items-center">
           <ActivityIndicator className="p-2 m-2" animating size="large" />
          </View>
         );
       }
      return isLogin ? <RootStack /> : <AuthStack />;
    }

    export default function Layout() {
      return (
        <AuthContextProvider>
          <StatusBar style="light" />
          <Root />
        </AuthContextProvider>
      );
    }

我尝试了 Chatgpt 并尝试阅读文档,甚至尝试关注某人的 YouTube 频道并指出有效

reactjs typescript react-native expo hybrid-mobile-app
1个回答
0
投票

您遇到的问题可能是由于在当前设置中同时安装了两个堆栈(RootStack 和 AuthStack)。

不是有条件地渲染两个堆栈 在根堆栈中,而是根据 isLogin 状态有条件地在堆栈导航器本身中渲染正确的堆栈。

例如。

import { router, Slot, Stack, Tabs } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { useContext, useEffect, useState } from "react";
import { AuthContext, AuthContextProvider } from "../context/AuthContext";
import { ActivityIndicator, View } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function Root() {
  const { setIsLogin, setToken, setIsTryingLogin, isTryingLogin, isLogin } =
    useContext(AuthContext);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const checkAuth = async () => {
      const token = await AsyncStorage.getItem("token");
      if (token) {
        console.log("token found, user logged in");
        setIsLogin(true);
        setToken(token);
      } else {
        setIsLogin(false);
      }
      // Set trying login to false after we check for token
      setIsTryingLogin(false);
    };

    checkAuth();
  }, []); // This runs only once on component mount

  useEffect(() => {
    if (!isTryingLogin) {
      setIsLoading(false);
    }
  }, [isTryingLogin]);

  if (isLoading) {
    console.log("Loading...");
    return (
      <View className="flex-1 justify-center items-center">
        <ActivityIndicator className="p-2 m-2" animating size="large" />
      </View>
    );
  }

  return (
    <Stack
      screenOptions={{
        headerShown: false, // Hides header for all screens by default
      }}
    >
      {isLogin ? (
        <>
          {/* Root Stack for authenticated users */}
          <Stack.Screen
            name="(root)/index"
            component={RootStack}
            options={{ title: "Welcome" }}
          />
        </>
      ) : (
        <>
          {/* Auth Stack for unauthenticated users */}
          <Stack.Screen
            name="(auth)/index"
            component={AuthStack}
            options={{ title: "Login Page" }}
          />
          <Stack.Screen
            name="(auth)/signup"
            component={AuthStack}
            options={{ title: "Sign Up Page" }}
          />
        </>
      )}
    </Stack>
  );
}

function RootStack() {
  return (
    <Stack>
      <Stack.Screen name="(root)/index" options={{ title: "Welcome" }} />
    </Stack>
  );
}

function AuthStack() {
  return (
    <Stack
      screenOptions={{
        headerStyle: { backgroundColor: "#6779ef" },
        headerTintColor: "white",
        contentStyle: { backgroundColor: "#6779ef" },
        headerShown: false,
      }}
    >
      <Stack.Screen name="(auth)/index" options={{ title: "Login Page" }} />
      <Stack.Screen name="(auth)/signup" options={{ title: "Sign Up Page" }} />
    </Stack>
  );
}

export default function Layout() {
  return (
    <AuthContextProvider>
      <StatusBar style="light" />
      <Root />
    </AuthContextProvider>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.