【问题标题】:Public and private routes in react using local storage使用本地存储做出反应的公共和私有路由
【发布时间】:2022-01-04 06:44:06
【问题描述】:

我正在尝试在我的项目中实现公共和私有路由。具有私有路由的未注释部分工作得很好,如果它没有经过身份验证,它会拒绝用户进入主页。 现在我正在尝试配置公共路由,这是注释部分,如果他登录,它将拒绝用户进入登录页面或注册,但它不起作用它会将我重定向到 /main 页面,即使他没有经过身份验证,也没有去登录或注册页面..虽然我读了很多关于这个主题的文章,但它对我不起作用......你能简要解释一下到底是什么问题吗? 我正在使用路由器 v5 可以看下面的代码

import React from "react";
import { Route, Redirect } from "react-router-dom";

const PrivateRoute = ({ component: Component, ...props }) => {
  const token = localStorage.getItem("isLogged");

  return (
    <Route
      {...props}
      render={(props) =>
        token ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
            }}
          />
        )
      }
    />
  );
};

export default PrivateRoute;

公共路线:

import React from "react";
import { Route, Redirect } from "react-router-dom";

const PublicRoute = ({ component: Component, ...props }) => {
  
  const token = localStorage.getItem("isLogged");

  return (
    <Route
      {...props}
      render={(props) =>
        token ? (
          <Redirect to={{ pathname: "/main" }} />
        ) : (
          <Component {...props} />
        )
      }
    ></Route>
  );
};

export default PublicRoute;

App.js:

import "./App.css";
import Login from "./Components/Login";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Main from "./Pages/Main";
import Home from "./Pages/Home";
import Register from "./Components/Register";
import PrivateRoute from "./routes/PrivateRoute";
import PublicRoute from "./routes/PublicRoute";

function App() {
  return (
    <Router>
      <div className="App"></div>

      <Switch>
        <Route path="/" exact component={Home}></Route>
        <Route path="/login" component={Login}></Route>
        <Route path="/register" component={Register}></Route>
        <PrivateRoute component={Main}></PrivateRoute>
      </Switch>
      {/* <Switch>
        <Route path="/" exact component={Home}></Route>
        <PublicRoute path="/login" component={Login} exact></PublicRoute>
        <PublicRoute path="/register" component={Register} exact />
        <PrivateRoute path="/main" component={Main} exact></PrivateRoute>
      </Switch> */}
    </Router>
  );
}

export default App;

【问题讨论】:

  • 你能检查一下token的价值吗? const token = localStorage.getItem("isLogged");
  • 你能在测试时检查一次吗> localStorage.getItem("isLogged") 这会给你一个布尔值或字符串
  • 我现在将值转换为布尔值,它正在工作,但现在当我想在登录和退出时浏览页面时,history.push() 不起作用?

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

问题

  1. 从 localStorage 获取的值很可能是字符串化的值,即 JSON,因此 token 值也可能是真值。
  2. token 值仅在自定义路由组件挂载时检查一次,而不是每次访问路由时检查一次。

解决方案

  1. 使用JSON.parse 解码/解析来自localStorage 的存储值。

    const token = JSON.parse(localStorage.getItem("isLogged"));
    

    确保您保存到 localStorage 的任何值也是一致的字符串化 JSON。

    localStorage.setItem("isLogged", JSON.stringify(true));
    
  2. token 访问/检查移入render 函数

    const PrivateRoute = ({ component: Component, ...props }) => {
      return (
        <Route
          {...props}
          render={(props) =>{
            const token = JSON.parse(localStorage.getItem("isLogged"));
            return token ? (
              <Component {...props} />
            ) : (
              <Redirect
                to={{
                  pathname: "/login"
                }}
              />
            )}
          }
        />
      );
    };
    
    const PublicRoute = ({ component: Component, ...props }) => {
      return (
        <Route
          {...props}
          render={(props) =>{
            const token = JSON.parse(localStorage.getItem("isLogged"));
            return token ? (
              <Redirect to={{ pathname: "/main" }} />
            ) : (
              <Component {...props} />
            )}
          }
        ></Route>
      );
    };
    

    简化您的自定义路由组件。

    const PrivateRoute = (props) => {
      const token = JSON.parse(localStorage.getItem("isLogged"));
      return token ? (
        <Route {...props} />
      ) : (
        <Redirect
          to={{
            pathname: "/login"
          }}
        />
      );
    };
    
    const PublicRoute = (props) => {
      const token = JSON.parse(localStorage.getItem("isLogged"));
    
      return token ? (
        <Redirect to={{ pathname: "/main" }} />
      ) : (
        <Route {...props} />
      );
    };
    

【讨论】:

    猜你喜欢
    • 2018-11-05
    • 2020-08-24
    • 2020-03-04
    • 2021-01-03
    • 1970-01-01
    • 2022-06-28
    • 2021-06-17
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多