如何在React Router v6 + vite + TS中创建受保护的路由[重复]

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

我正在尝试在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]);
reactjs react-router react-router-dom redux-toolkit
1个回答
-1
投票

您可以创建一个名为 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

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