如何让React Router v6在单页应用程序中进行身份验证后加载正确的组件?

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

当用户通过谷歌身份验证(

onAuthStateChanged
)进行身份验证时,有时未加载根路径的正确组件,我会得到一个空白页面。

我正在尝试根据

"/"
的状态在
user
路线中加载不同的组件:

<Login />
= 未经过身份验证

<Home />
=
user.role
是用户

<Admin />
=
user.role
是管理员

我尝试在 Login.jsx 文件和 AuthContext.jsx 文件中添加

<Navigate to="/" replace />
。我已经尝试添加
location.reload()
调用,但它导致了无限循环。

我知道当我设置状态(

setUser
)时,状态更改是异步的,只有在下一次渲染时 React 才会更新它。

当我将

console.log
语句放入代码中(用于调试)时,它工作得很好。

此外,如果我手动刷新页面(当页面为空白时),正确的组件会加载得很好。

在身份验证状态更改后通过 React Router 6 重新渲染根组件的最佳实践是什么?

AuthContext.jsx

import { useState, useEffect, createContext } from "react";
import { auth } from "./firebaseInit";

export const AuthContext = createContext();

export const AuthContextProvider = ({children}) => {
  const [user, setUser] = useState(null);

  useEffect( () => {
    const unsubscribe = auth.onAuthStateChanged( async (auth_user) => {
      if (auth_user) {
        if (auth_user.emailVerified) {
          // api call to grab user data
          setUser(auth_user);

          // SHOULD I PUT THIS HERE?
          // return <Navigate to="/" replace />
        }
      }
    });

    return () => {
      unsubscribe();
    }

  }, []);

  return (
    <AuthContext.Provider
      value={{user}}
    >
      {children}
    </AuthContext.Provider>
  );
};

登录.jsx

import { Navigate } from "react-router-dom";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../../backend/firebaseInit";

export default function Login() {
  const handleSubmit = async (e) => {
    e.preventDefault();
    const data = new FormData(e.currentTarget);
    
    signInWithEmailAndPassword(auth, data.get('email'), data.get('password') )
    .then( async (userCredential) => {
       const auth_user = userCredential.user;
       if (auth_user) {
         // ADDING THIS MAKES IT WORK
         //console.log('i am about to navigate');

         // SHOULD I PUT THIS HERE?
         //return <Navigate to="/" replace />;
       }
     })
     .catch((err) => {
       console.log(err.toString());
     })
  };

  return (
    <Container >
      <Box>
        // login form
      </Box>
    </Container>
  );
}

路由.jsx

import { AuthContext } from './AuthContext';
import { useContext } from 'react';
import { BrowserRouter, Routes, Route } from'react-router-dom';

export default function ConvuRouter() {
  const {user} = useContext(AuthContext);

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={user ? ( user.role === 'admin' ? <Admin /> : (user.role === 'user' ? <Home /> : <Login /> ) ) : <Login /> } />
      </Routes>
    </BrowserRouter>
  );
};
reactjs react-router google-oauth
1个回答
-1
投票

问题可能是user.role尚未更新;当您导航到“/”时,您可以尝试添加加载状态,它将指示身份验证过程是否仍在进行中。如果是,您可以选择渲染加载微调器。

© www.soinside.com 2019 - 2024. All rights reserved.