我正在尝试在React Router dom vs 6中创建一条受保护的路由,但我有一些问题一一显示,比如刷新页面变为空白,然后修复页面后仅返回登录任何人都可以帮助我,
我使用一些新的 api(例如 createBrowserRouter)尝试了不同的解决方案,但总是发现不同的问题
import React from "react";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import HomePage from "../pages/HomePage";
import Login from "../sign/Admin/Login";
import Signup from "../sign/Admin/Signup";
import { RootState } from "../../store";
import { useSelector } from "react-redux";
import CategoryPage from "../pages/CategoryPage";
import StorePage from "../pages/StorePage";
import ProductPage from "../pages/ProductPage";
import ServicePage from "../pages/ServicePage";
import UserPage from "../pages/UserPage";
import AdminPage from "../pages/AdminPage";
import OrderPage from "../pages/OrderPage";
interface ICutomeRoutes {
token: boolean;
}
const CutomeRoutes: React.FC<ICutomeRoutes> = ({ token }) => {
// const { isLoading, error, errorMessage } = useSelector((state: RootState) => state.admin);
return (
<BrowserRouter>
<Routes>
<Route path="/" element={token ? <HomePage /> : <Navigate to="/login" />} />
<Route path="/categories" element={token ? <CategoryPage /> : <Navigate to="/login" />} />
<Route path="/stores" element={token ? <StorePage /> : <Navigate to="/login" />} />
<Route path="/products" element={token ? <ProductPage /> : <Navigate to="/login" />} />
<Route path="/services" element={token ? <ServicePage /> : <Navigate to="/login" />} />
<Route path="/users" element={token ? <UserPage /> : <Navigate to="/login" />} />
<Route path="/admins" element={token ? <AdminPage /> : <Navigate to="/login" />} />
<Route path="/orders" element={token ? <OrderPage /> : <Navigate to="/login" />} />
<Route path="/login" element={!token ? <Login /> : <Navigate to="/" />} />
<Route path="/signup" element={!token ? <Signup /> : <Navigate to="/" />} />
</Routes>
</BrowserRouter>
);
};
export default CutomeRoutes;
应用程序.tsx
import useLocalizeDocumentAttributes from "./i18n/useLocalizeDocumentAttributes";
import { AppDispatch, RootState } from "./store";
import { useDispatch, useSelector } from "react-redux";
import { useEffect, useState } from "react";
import { getAdminByToken } from "./store/slices/admin";
import CutomeRoutes from "./components/routes";
import Loader from "./components/ui/loaders/Loader";
function App() {
useLocalizeDocumentAttributes();
const dispatch = useDispatch<AppDispatch>();
const [token, setToken] = useState<string | null>(null);
const { isLoading, error, errorMessage } = useSelector((state: RootState) => state.admin);
console.log({ token: token });
useEffect(() => {
const tokenFromStorage = localStorage.getItem("user-token");
console.log("token is", token);
if (tokenFromStorage) {
setToken(tokenFromStorage);
dispatch(getAdminByToken(token));
}
}, [dispatch]);
// if (token === null) {
if (isLoading) {
return <Loader />; // You can render a loader or any other UI while fetching token
}
return (
<>
<CutomeRoutes token={!!token} />
</>
);
}
export default App;
处理登录
const onSubmit: SubmitHandler<FormFields> = async (inputData, event) => {
try {
console.log(inputData);
if (loginKey) {
// If loginKey exists, dispatch acceptLoginKey action
dispatch(acceptAdminLoginKey({ phone: inputData.phoneNumber, loginKey: parseInt(inputData.loginKey) }));
} else {
dispatch(loginAdmin(inputData.phoneNumber));
}
} catch (error) {
console.log(error);
setError("root", {
message: "There's something wrong " + error,
});
}
};
useEffect(() => {
if (token) {
const { from } = location.state || { from: { pathname: "/" } };
navigate(from, { replace: true });
}
}, [token]);
您可以创建一个名为 PrivateRoutes 的新组件来解决此问题,并将所有路由包装在单个组件中。
import { Navigate, Outlet } from 'react-router-dom'
const PrivateRoutes = () => {
let auth = {'token':true}
return (
auth.token ? <Outlet/> : <Navigate to='/login'/>
)
}
然后你可以像这样重写应用程序代码:
<Router>
<Routes>
<PrivateRoutes>
<Route path="/protected" element={...} />
</PrivateRoutes>
</Routes>
</Router>
供以后参考:https://medium.com/@dennisivy/creating-protected-routes-with-react-router-v6-2c4bbaf7bc1c