我使用來自 Firebase v9 和 React-router-dom v6 的 auth API 構建了一個私有路由來訪問管理部分,當我登錄它時,它會將我重定向到管理頁面,但頁面是空白的,控制臺記錄了這個“ React.jsx :型別無效——需要一個字串(對于內置組件)或一個類/函式(對于復合組件),但得到:未定義。 ”并讓我“在 PrivateRoute.jsx:7 檢查你的代碼。 ”。謝謝你的幫助=)。
私有路由.jsx
import React from 'react'
import {Navigate} from 'react-router-dom'
import { auth } from '../../Firebase'
function PrivateRoute({component: Component}) {
const user = auth.currentUser
return user ? <Component /> : <Navigate to='/login'/>
}
export default PrivateRoute
App.jsx(使用私有路由的地方)
import {BrowserRouter, Route, Routes } from 'react-router-dom';
import Admin from './Components/Admin/Admin'
function App() {
return (
<BrowserRouter>
<div className="App">
<Routes>
<Route
path="/admin"
element={
<PrivateRoute>
<Admin />
</PrivateRoute>
}
/>
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
我讓你看看 Firebase 檔案和 AuthContext
Firebase.js
import {initializeApp} from 'firebase/app'
import {serverTimestamp, getFirestore} from 'firebase/firestore'
import {getStorage} from 'firebase/storage'
import {getAuth} from'firebase/auth'
const firebaseConfig = { config }
const app = initializeApp(firebaseConfig)
export const timestamp = serverTimestamp()
export const projectFirestore= getFirestore(app)
export const projectStorage= getStorage(app)
export const auth = getAuth(app)
export default app
AuthContext.jsx
import {useContext, useState, useEffect, createContext} from 'react'
import { auth } from '../../Firebase'
import { createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, onAuthStateChanged} from "firebase/auth";
const AuthContext = createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({children}) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function register(email, password){
return createUserWithEmailAndPassword(auth, email, password)
}
function login(email, password){
return signInWithEmailAndPassword(auth, email, password)
}
function logout() {
signOut(auth)
}
useEffect(() =>{
const unsubscribe = onAuthStateChanged(auth ,(user) => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
register,
logout
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
uj5u.com熱心網友回復:
RRDv6 中的身份驗證方式與 v5 相比發生了顯著變化。自定義路由組件已經一去不復返了,取而代之的是包裝器組件。
鑒于:
<BrowserRouter>
<div className="App">
<Routes>
<Route
path="/admin"
element={(
<PrivateRoute>
<Admin />
</PrivateRoute>
)}
/>
</Routes>
</div>
</BrowserRouter>
該PrivateRoute包裝只需要渲染的children道具代替的component道具。
function PrivateRoute({ children }) {
const user = auth.currentUser;
return user ? children : <Navigate to='/login' replace />;
}
然而,一種常見的模式是在Outlet組件中呈現,并包裝嵌套的受保護路由。
例子:
import { Navigate, Outlet } from 'react-router-dom';
const PrivateWrapper = () {
const user = auth.currentUser;
return user ? <Outlet /> : <Navigate to='/login' replace />;
}
...
<BrowserRouter>
<div className="App">
<Routes>
<Route path="/admin" element={<PrivateWrapper />} >
<Route path="/admin" element={<Admin />} />
... other nested protected routes ...
</Route>
</Routes>
</div>
</BrowserRouter>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/375803.html
