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"));
我正在尝试为管理页面创建路由。代码可以在下面找到。我当前的问题是我的 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"));