8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

登录后,如何在 React 中重新渲染 AuthProvider

Huda Twfik 1月前

9 0

我的项目的身份验证流程是:AuthProvider 封装了所有路由,AuthProvider 具有 useEffect,它会调用 verifyToken API 来检查令牌的有效性。当用户提交登录表单时,令牌就会被发送到...

我的项目的身份验证流程是:AuthProvider 封装了所有路由,AuthProvider 具有 useEffect,它调用 verifyToken API 来检查令牌的有效性。当用户提交登录表单时,从后端设置令牌,并且页面导航到受保护的路由:受保护的路由从 AuthProvider 获取身份验证,检查令牌是否有效。

我的问题是,在用户登录之前,AuthProvider 调用 API 并且所有内容都设置为 false。因此,导航到受保护的路由会发送回登录。我必须手动输入域/仪表板来强制重新渲染所有内容,以便 AuthProvider 再次将真正的有效数据发送到受保护的路由。

这是我的AuthProvier:

import { useVerifyToken } from "@/Auth/hooks/useAuthQuery";
import { ReactNode, useEffect, useState } from "react";
import { AuthContext } from "../hooks/AuthContext";


interface AuthProviderProps {
    children: ReactNode;
}
export const AuthProvider = ({ children }: AuthProviderProps) => {
    const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
    const { data: validUserDetails, isLoading:verifyTokenLoading, isSuccess, isError } = useVerifyToken();

    useEffect(() => {
        if (validUserDetails && isSuccess) {
            setIsAuthenticated(true);
            sessionStorage.setItem('validUserDetails', JSON.stringify(validUserDetails));
        }
        else if (isError) {
            setIsAuthenticated(false);
            sessionStorage.removeItem('validUserDetails');
        }
    }, [validUserDetails, isSuccess, isError])

    console.trace(isAuthenticated)

    return (
        <AuthContext.Provider value={{isAuthenticated,verifyTokenLoading}}>
            {children}
        </AuthContext.Provider>
    )
}

这是AuthContext:

import { createContext } from "react";

interface AuthContextValue {
  isAuthenticated: boolean;
  verifyTokenLoading: boolean;
}

export const AuthContext = createContext<AuthContextValue>({
  isAuthenticated: false,
  verifyTokenLoading: false,
});

这是 ProtectedRoute 组件:

import Sidebar from "@/Common/pages/Sidebar"
import { Navigate, Outlet } from "react-router-dom"
import Spinner from '@/Common/Utils/Spinner'
import { useContext } from "react"
import { AuthContext } from "@/Common/hooks/AuthContext";

function ProtectedRoute() {
    const {isAuthenticated,verifyTokenLoading} =useContext(AuthContext);

    if (verifyTokenLoading) {
        return (
            <Spinner />
        )
    }

    if (!isAuthenticated) {
        return <Navigate to={'/auth/login'} replace />
    }

    return (
        <section className="flex">
            <section className="w-[23%] min-h-screen">
                <Sidebar />
            </section>
            <section className="w-full px-4 py-4 bg-tertiary/5 min-h-screen">
                <Outlet />
            </section>
        </section>
    )
}

export default ProtectedRoute

这是我的路线:

import {createBrowserRouter, Navigate} from 'react-router-dom';
import App from './App';
import Auth from './Auth/views/Index';
import LoginForm from './Auth/components/LoginForm';
import SignupForm from './Auth/components/SignupForm';
import ForgetPassword from './Auth/components/ForgetPassword';
import NotFoundPage from './Common/pages/NotFoundPage';
import ErrorPage from './Common/pages/ErrorPage';
import ProtectedRoute from './Auth/components/ProtectedRoute';
import Dashboard from '@/Dashboard/views/Index';
import MyProjects from '@/MyProjects/views/Index';
import Calendar from '@/Calendar/views/Index';

export const routes=createBrowserRouter([
    {
        path:'',
        element:<App/>,
        children:[
            {
                path:'auth',
                element:<Auth/>,
                children:[
                    {
                        path:'',
                        element:<Navigate to={'/auth/login'} replace/>
                    },
                    {
                        path:'login',
                        index:true,
                        element:<LoginForm/>
                    },
                    {
                        path:'signup',
                        element:<SignupForm/>
                    },
                    {
                        path:'forgetpassword',
                        element:<ForgetPassword/>
                    }
                ]
            },
            {
                path:'',
                element:<ProtectedRoute/>,
                children:[
                    {
                        index:true,
                        element:<Navigate to={'/dashboard'}/>
                    },
                    {
                        path:'dashboard',
                        element:<Dashboard/>
                    },
                    {
                        path:'myprojects',
                        element:<MyProjects/>
                    },
                    {
                        path:'calendar',
                        element:<Calendar/>
                    }
                ]
            }
            
        ],
        errorElement:<ErrorPage/>
    },
    {
        path:'*',
        element:<NotFoundPage/>
    }
])

这是我使用反应查询的 APICalls:

import { ApiManager } from "@/Common/Services/TaskItApi/ApiManager";
import { AuthEndpoints } from "@/Common/Services/TaskItApi/Endpoints";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { SignUp } from "../components/SignupForm";
import { LoginData } from "../components/LoginForm";
import { toast } from "sonner";

export const useSignUp = () => {
  return useMutation({
    mutationFn: async (data:SignUp) => {
      const response = await ApiManager.post(AuthEndpoints.signUp(), data);
      return response;
    },
    onError:(error)=>{
        toast.error(error.message)
    },
    onSuccess:()=>{
        toast.success('Account Registered Successfully')
    }
  });
};

export const useLogin = () => {
  const queryClient=useQueryClient();
  return useMutation({
    mutationFn: async (data:LoginData) => {
      queryClient.invalidateQueries({queryKey:['validUserDetails']})
      const response = await ApiManager.post(AuthEndpoints.login(), data);
      return response;
    },
    onError:(error)=>{
        toast.error(error.message)
    }
  });
};

export const useVerifyToken=()=>{
  return useQuery({
    queryKey:['validUserDetails'],
    queryFn:async()=>{
      const response =await ApiManager.get(AuthEndpoints.verifyToken());
      return response;
    },
    retry:0,
  })
}

export const useLogout=()=>{
  const queryClient=useQueryClient();
  return useMutation({
    mutationFn:async()=>{
      const response=await ApiManager.post(AuthEndpoints.logout(),{});
      return response;
    },
    onSuccess:()=>{
      queryClient.invalidateQueries({queryKey:['validUserDetails']})
      toast.success('Logout Successful')
    },
    onError:(error)=>{
      toast.error(error.message)
    }
  })
}

我可以尝试,根据更改的令牌强制重新渲染 AuthProvider。但我也找不到这样做的方法。

帖子版权声明 1、本帖标题:登录后,如何在 React 中重新渲染 AuthProvider
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Huda Twfik在本站《authentication》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我想确认您是否有可能监督那里的社会福利项目。涉及的金额为 7,800,000.00 美元。为了让我有足够的信心披露更多细节,请通过以下方式联系我: https://t.me/laurahmaxwel 。很高兴收到您的来信?

返回
作者最近主题: