【问题标题】:How to create a private route in react js using redux and typescript?如何使用 redux 和 typescript 在 react js 中创建私有路由?
【发布时间】:2022-01-09 17:10:26
【问题描述】:

我的 github 代码中有一个问题,我不知道如何解决。我是 redux 和路由器 v6 的新手。我在我的项目中使用打字稿,这造成了更多的混乱,有人可以帮我解决这个问题吗?

我的问题是

只有在授权用户登录时才能访问管理仪表板。但该路由是公开访问的。

https://github.com/neeteshraj/finisterre-frontend/issues/1

这是我的 app.tsx 文件

import React from 'react';
import { BrowserRouter, Route, Routes} from 'react-router-dom';
import {Home, Signup, Signin} from './container/index';
import './App.css';
import PrivateRoute from './components/common/HOC/Index';


function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Routes>
          <Route path={"/"} element={<PrivateRoute/>}>
            <Route path={"/"} element={<Home/>} />
          </Route>
          <Route path={"/signup"} element={<Signup/>}/>
          <Route path={"/signin"} element={<Signin/>}/>
        </Routes>
      </BrowserRouter>
    </div>
  );
}



export default App;

这是我的 privaterouter.tsx 组件

import React from 'react';
import { BrowserRouter, Routes,Route, Navigate,useNavigate, Outlet } from 'react-router-dom';
import authReducer from '../../../reducers/auth-reducers';



const PrivateRoute = (props:any) => {

    return (
        <Outlet {...props} component={(props:any)=>{
            const token = window.localStorage.getItem('token');
            if(token){
                return <props.component {...props}/>
            }
            else{
                return <Navigate to={`/signin`}/>
            }
        }}
        />
    )
}



export default PrivateRoute;

【问题讨论】:

  • 如果您不发布任何需要帮助的代码,没有人可以帮助您。
  • 我尝试发布了两次 :( 但没有人帮助。
  • 代码贴在哪里?此问题中没有发布代码。
  • 你能把代码粘贴到这里,而不是链接到 Github 吗?这将使回答您的问题变得更加容易。
  • 代码粘贴在这里。你可以去看看。

标签: javascript reactjs typescript redux


【解决方案1】:

好吧,因为我不知道你是否想要嵌套路由,所以我想我会在这里帮助你一点。由于您没有发布与 redux 相关的任何内容,因此我将其省略了。这是一个包含嵌套路由和普通路由 Codesandbox 的工作代码框。

在下面的示例中,我只是使用了一个工作示例,因此我只是使用状态来控制令牌。您可以稍后将其转入您的const token = window.localStorage.getItem('token');,但我想要一个您可以轻松遵循的示例。而且由于我不知道您的代码的范围,我认为只给您一个工作示例会更容易。

这是一个没有嵌套路由的普通示例:

import React, { useState } from "react";
import {
  BrowserRouter,
  Routes,
  Route,
  Link,
  Navigate,
  useLocation,
  useNavigate
} from "react-router-dom";

const Component: React.FC<{ title: string }> = ({ title }) => <h1>{title}</h1>;

const PrivateRoute: React.FC<{ token: boolean }> = ({ token, children }) => {
  const location = useLocation();

  return token ? (
    <>{children}</>
  ) : (
    <Navigate to="/login" state={{ from: location }} />
  );
};

const Login: React.FC<{ setToken: any }> = ({ setToken }) => {
  const navigate = useNavigate();
  const location: any = useLocation();
  let from = location.state?.from?.pathname || "/";

  const handleLogin = () => {
    setToken(true);
    navigate(from, { replace: true });
  };

  return <button onClick={handleLogin}>Login</button>;
};

export default function App() {
  const [token, setToken] = useState<boolean>(false);

  return (
    <div className="App">
      <BrowserRouter>
        <Link to="/">Home</Link> | <Link to="/dashboard">Dashboard</Link>
        <Routes>
          <Route path="/" element={<Component title="Home" />} />
          <Route path="/login" element={<Login setToken={setToken} />} />
          <Route path="/dashboard" element={
            <PrivateRoute token={token}>
              <Component title="Dashboard"/>
            </PrivateRoute>
          } />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

所以你可以看到在私有路由组件中我们正在检查令牌。如果有一个令牌,那么我们将只渲染孩子,否则我们将导航到登录页面。在登录页面中,我们提供登录功能,然后我们将获取位置状态,一旦登录,我们将自动将用户重定向到他们尝试访问的页面。

这是一个嵌套路由示例:

import React, { useState } from "react";
import {
  BrowserRouter,
  Routes,
  Route,
  Link,
  Navigate,
  Outlet,
  useLocation,
  useNavigate
} from "react-router-dom";

const Component: React.FC<{ title: string }> = ({ title }) => <h1>{title}</h1>;

const PrivateRoute: React.FC<{ token: boolean }> = ({ token, children }) => {
  const location = useLocation();

  return token ? (
    <>{children}</>
  ) : (
    <Navigate to="/dashboard/login" state={{ from: location }} />
  );
};

const Login: React.FC<{ setToken: any }> = ({ setToken }) => {
  const navigate = useNavigate();
  const location: any = useLocation();
  let from = location.state?.from?.pathname || "/";

  const handleLogin = () => {
    setToken(true);
    navigate(from, { replace: true });
  };

  return <button onClick={handleLogin}>Login</button>;
};

const Dashboard: React.FC = () => {
  return (
    <div>
      <Outlet />
    </div>
  );
};

export default function App() {
  const [token, setToken] = useState<boolean>(false);

  return (
    <div className="App">
      <BrowserRouter>
        <Link to="/">Home</Link> | <Link to="/dashboard">Dashboard</Link>
        <Routes>
          <Route path="/" element={<Component title="Home" />} />
          <Route path="/dashboard" element={<Dashboard />}>
            <Route
              path="/dashboard"
              element={
                <PrivateRoute token={token}>
                  <Component title="Dashboard" />
                </PrivateRoute>
              }
            />
            <Route
              path="/dashboard/login"
              element={<Login setToken={setToken} />}
            />
          </Route>
        </Routes>
      </BrowserRouter>
    </div>
  );
}

在这里您可以看到我们在仪表板组件中使用插座作为占位符。这让反应路由器知道我们想要渲染一些嵌套路由。如果你想将你的路由嵌套在仪表板组件中,那么你不需要使用出口组件,你可以这样做:

const Dashboard: React.FC<{ token: boolean; setToken: any }> = ({
  token,
  setToken
}) => {
  return (
    <div>
      <Routes>
        <Route
          path="/"
          element={
            <PrivateRoute token={token}>
              <Component title="Dashboard" />
            </PrivateRoute>
          }
        />
        <Route path="/login" element={<Login setToken={setToken} />} />
      </Routes>
    </div>
  );
};

export default function App() {
  const [token, setToken] = useState<boolean>(false);

  return (
    <div className="App">
      <BrowserRouter>
        <Link to="/">Home</Link> | <Link to="/dashboard">Dashboard</Link>
        <Routes>
          <Route path="/" element={<Component title="Home" />} />
          <Route
            path="/dashboard/*"
            element={ <Dashboard token={token} setToken={setToken} /> } />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

【讨论】:

    猜你喜欢
    • 2023-02-08
    • 2020-08-13
    • 1970-01-01
    • 2022-01-17
    • 2018-03-05
    • 2021-06-04
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多