React Routing 无法正确路由

React Routing unable to route properly

我正在尝试为管理页面创建路由。代码可以在下面找到。我当前的问题是我的 currentUser 有我的认证用户 obj 并且 userType 是 False,但我仍然可以访问 /createUser 页面。

AdminRoute.js

import React from 'react' 
import { Route, Redirect } from 'react-router-dom' 
import { useAuth } from '../../contexts/AuthContext' 
 
const AdminRoute = (props) => { 
    const { currentUser } = useAuth(); 
    const userType = localStorage.getItem('admin'); 
 
    if (currentUser === undefined) { 
        return null; 
    } 
    console.log(userType) 
 
    return currentUser && userType 
    ? ( 
      <Route {...props} /> 
    ) 
    : ( 
      <Redirect to={{ 
        pathname: "/homepage", 
        state: { 
          from: props.location 
        } 
      }} /> 
    ) 
} 
 
export default AdminRoute

Route.js

<Router> 
     <Switch>                
          <AdminRoute path='/createUser' component={Register} /> 
     </Switch>
</Router>

第一步: Login.js

async function handleSubmit(e) { 
        e.preventDefault() 
        try { 
            setError('') 
            setLoading(true) 
            await login(emailRef.current.value, passwordRef.current.value) 
 
            history.push('/homepage') 
        } catch { 
            console.log("heh") 
        } 
 
        setLoading(false) 
    }

第 2 步:HandleSubmit 将从 AuthContext.js 调用函数。

这是 AuthContext.js 在 firebase

进行身份验证后我获得 currentUser 的地方
import React, { useContext, useState, useEffect } from "react" 
import { auth, database } from "../firebase"; 
import { getDocs, query, where } from "firebase/firestore"; 
 
const AuthContext = React.createContext() 
 
export function useAuth() { 
    return useContext(AuthContext) 
} 
 
export function AuthProvider({ children }) { 
    const [currentUser, setCurrentUser] = useState(null) 
    const [loading, setLoading] = useState(true) 
 
    function login(email, password) { 
        return auth.signInWithEmailAndPassword(email, password).then(() => { 
            const Doc = query(database.usersRef, where("email", "==", email)); 
 
            getDocs(Doc).then((querySnapshot) => { 
                let values = ''; 
 
                querySnapshot.forEach((doc) => { 
                    values = doc.id; 
                    
                    // Setting user type in session storage 
                    if (doc.data().userType === "Administrator") { 
                        localStorage.setItem('admin', false); 
                    } else { 
                        localStorage.setItem('admin', false); 
                    }
                }); 
 
                var userUpdate = database.usersRef.doc(values); 
                userUpdate.update({ 
                    lastActive: new Date().toLocaleString('en-SG'), 
                }) 
            }) 
        }); 
    } 
 
    function logout() { 
        return auth.signOut(); 
    } 
 
    function forgetPassword(email) { 
        return auth.sendPasswordResetEmail(email); 
    } 
 
    function updateEmail(email) { 
        return currentUser.updateEmail(email) 
    } 
 
    function updatePassword(password) { 
        return currentUser.updatePassword(password) 
    } 
 
    function updateDisplayName(name) { 
        return currentUser.updateDisplayName(name) 
    } 
 
    useEffect(() => { 
        const unsubscribe = auth.onAuthStateChanged( user => { 
            setLoading(false) 
            setCurrentUser(user) 
        }) 
 
        return unsubscribe 
    }, []) 
 
    const value = { 
        currentUser, 
        login, 
        forgetPassword, 
        logout, 
        updateEmail, 
        updatePassword, 
        updateDisplayName, 
    } 
 
    return ( 
        <AuthContext.Provider value={value}> 
            {!loading && children} 
        </AuthContext.Provider> 
    ) 
}

我想我明白了。代码不是 JSON serializing/deserializing "admin" 状态,它正在持久化并从 localStorage 加载。

在您的控制台中 运行:

localStorage.setItem('admin', false)
const userType = localStorage.getItem('admin')
typeof userType
userType

localStorage.getItem('admin'); returns 一个 JSON 字符串,"false",当您控制台记录它时,您看不到引号。 "false" 是一个真值,因此 currentUser && userType 布尔表达式计算 true 当用户通过身份验证并且在 "admin" 键下的 localStorage 中存储了一个值。

你应该总是 JSON serialize/deserialize to/from localStorage。

const AdminRoute = (props) => { 
  const { currentUser } = useAuth(); 
  const userType = JSON.parse(localStorage.getItem('admin') ?? false); 
 
  if (currentUser === undefined) { 
    return null; 
  } 
 
  return currentUser && userType 
    ? ( 
      <Route {...props} /> 
    ) 
    : ( 
      <Redirect to={{ 
        pathname: "/homepage", 
        state: { 
          from: props.location 
        } 
      }} /> 
    );
}

登录

...

// Setting user type in session storage 
localStorage.setItem('admin', JSON.stringify(doc.data().userType === "Administrator"));