打开应用程序时,将加载第一个登录屏幕,然后移动到博览会反应本机中的主屏幕

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

我使用 JWT 令牌为我的应用程序使用 React 上下文 API 进行持久登录。

当关闭和打开应用程序时,首先加载登录屏幕,然后加载主屏幕,如何解决延迟。从 VS 代码重新加载时也会发生同样的事情。

import { createContext, useContext, useEffect, useState } from "react";
import axios from "axios";
import * as SecureStore from 'expo-secure-store';
import { handleError } from "../utils/helperFunctions";
import { API_URL, AUTH_KEY } from "../constants/strings";
import { setAxiosAuthHeader } from "../utils/configHelpers";
import { AuthProps, ILoginDeatils } from "../interface/AuthInterface";

const AuthContext = createContext<AuthProps>({});

export const useAuth = () => {
    return useContext(AuthContext);
}

export const AuthProvider = ({ children }: any) => {
    const [authState, setAuthState] = useState<ILoginDeatils>(InitialLoginState);
    const [loading, setLoading] = useState<boolean>(false);

    useEffect(() => {
        setLoading(true);
        const loadUserAuthState  = async () => {
            const loggedInDetails = await SecureStore.getItemAsync(AUTH_KEY);
            if (loggedInDetails) {
                const loggedInUserDetails:ILoginDeatils = JSON.parse(loggedInDetails);
                setAxiosAuthHeader(loggedInUserDetails.token);
                setAuthState(loggedInUserDetails);
            }
        };
        loadUserAuthState();
        setLoading(false);
    }, [])


    const login = async (email: string, password: string) => {
        const loginInfo = { email, password };
        const result = await axios.post(`${API_URL}/auth/login`, loginInfo);
        if (!result.data.verified || !result.data.completedProfile) {
            return result;
        }
        const loggedInDetails: ILoginDeatils = {
            registerId: result.data.loginDetils.registerId,
            gender: result.data.loginDetils.gender,
            email: result.data.loginDetils.email,
            profileId: result.data.loginDetils.profileId,
            name: result.data.loginDetils.name,
            phone: result.data.loginDetils.phone,
            token: result.data.token,
            authenticated: true
        }
        await SecureStore.setItemAsync(AUTH_KEY, JSON.stringify(loggedInDetails));
        setAxiosAuthHeader(loggedInDetails.token);
        setAuthState(loggedInDetails)
        return result;
    }

    const logout = async () => {
        // Delete token from stroage
        await SecureStore.deleteItemAsync(AUTH_KEY);
        // Update HTTP Headers 
        setAxiosAuthHeader("")
        // Reset auth state
        setAuthState(InitialLoginState);
        Promise.resolve(true);
    }
    
    const value = {
        onRegister: register,
        onLogin: login,
        onLogout: logout,
        authState,
        loading,
        setAuthState
    };

    return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}
App.tsx

import 'react-native-gesture-handler';
import { useFonts } from 'expo-font';
import React, { useEffect } from 'react';
import * as SplashScreen from 'expo-splash-screen';
import { PaperProvider } from 'react-native-paper';
import FlashMessage from "react-native-flash-message";

import { fontsFamily } from './src/styles/fonts';
import { FormsProvider } from './src/context/FormsContext';
import { AuthProvider } from './src/context/AuthContext';
import { ThemeProvider } from './src/theme/ThemeProvider';
import AppNavigation from './src/navigations/AppNavigation';

SplashScreen.preventAutoHideAsync();

export default function App() {
  const [fontsLoaded, fontError] = useFonts(fontsFamily);

  useEffect(() => {
    if (fontsLoaded || fontError) {
      SplashScreen.hideAsync();
    }
  }, [fontsLoaded, fontError]);

  if (!fontsLoaded && !fontError) {
    return null;
  }

  return (
    <PaperProvider>
      <ThemeProvider>
        <FormsProvider>
          <AuthProvider>
            <AppNavigation />
          </AuthProvider>
        </FormsProvider>
      </ThemeProvider>
      <FlashMessage />
    </PaperProvider>
  );
}
AppNavigation.tsx
import React from 'react'
import { useAuth } from '../context/AuthContext';
import ExpoStatusBar from 'expo-status-bar/build/ExpoStatusBar';
import { NavigationContainer } from '@react-navigation/native';
import SideDrawer from './drawer/SideDrawer';
import Auth from './stack/Auth';
import { useAMTheme } from '../theme/ThemeProvider';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import AnimatedSplashScreen from '../components/uiElements/loader/AnimatedSplashScreen';

const AppNavigation = () => {
    const { authState, loading } = useAuth();
    const { isDark } = useAMTheme();
    
    if(loading){
        return <AnimatedSplashScreen/>
    }
    return (
        <GestureHandlerRootView style={{ flex: 1 }}>
            <ExpoStatusBar style={isDark ? "light" : "dark"} backgroundColor={'transparent'} />
            {
                authState?.authenticated ? (
                    <NavigationContainer>
                        <SideDrawer />
                    </NavigationContainer>
                ) : (
                    <NavigationContainer>
                        <Auth />
                    </NavigationContainer>
                )
            }
        </GestureHandlerRootView>
    )
}

export default AppNavigation

请有人帮忙解决这个问题或分享任何 github 项目以供参考

问题视频链接:https://drive.google.com/file/d/1dnM6IIV5jCvzbrJuf1cV3ElVW7segKSZ/view?usp=drive_link

react-native authentication jwt expo react-context
1个回答
0
投票

loadUserAuthState
函数异步运行,因此
setLoading(false)
将在准备好之前执行。解决此问题的一种方法是在函数内移动加载状态处理。像这样的东西:

useEffect(() => {
  const loadUserAuthState = async () => {
    setLoading(true);
...
    setLoading(false);
  };
  loadUserAuthState();
}, []);
© www.soinside.com 2019 - 2024. All rights reserved.