reactjs - 如何创建 protected 路由?

标签 reactjs react-router react-router-dom

如何使用 react-router-dom 创建 protected 路由并将响应存储在本地存储中,以便用户下次尝试打开时可以再次查看其详细信息。登录后,他们应该重定向到仪表板页面。
所有功能都添加到 ContextApi 中。
代码沙盒链接:Code
我尝试过但无法实现
路线页面

import React, { useContext } from "react";
import { globalC } from "./context";
import { Route, Switch, BrowserRouter } from "react-router-dom";
import About from "./About";
import Dashboard from "./Dashboard";
import Login from "./Login";
import PageNotFound from "./PageNotFound";

function Routes() {
  const { authLogin } = useContext(globalC);
  console.log("authLogin", authLogin);

  return (
    <BrowserRouter>
      <Switch>
        {authLogin ? (
          <>
            <Route path="/dashboard" component={Dashboard} exact />
            <Route exact path="/About" component={About} />
          </>
        ) : (
          <Route path="/" component={Login} exact />
        )}

        <Route component={PageNotFound} />
      </Switch>
    </BrowserRouter>
  );
}
export default Routes;

上下文页面
import React, { Component, createContext } from "react";
import axios from "axios";

export const globalC = createContext();

export class Gprov extends Component {
  state = {
    authLogin: null,
    authLoginerror: null
  };
  componentDidMount() {
    var localData = JSON.parse(localStorage.getItem("loginDetail"));
    if (localData) {
      this.setState({
        authLogin: localData
      });
    }
  }

  loginData = async () => {
    let payload = {
      token: "ctz43XoULrgv_0p1pvq7tA",
      data: {
        name: "nameFirst",
        email: "internetEmail",
        phone: "phoneHome",
        _repeat: 300
      }
    };
    await axios
      .post(`https://app.fakejson.com/q`, payload)
      .then((res) => {
        if (res.status === 200) {
          this.setState({
            authLogin: res.data
          });
          localStorage.setItem("loginDetail", JSON.stringify(res.data));
        }
      })
      .catch((err) =>
        this.setState({
          authLoginerror: err
        })
      );
  };
  render() {
    // console.log(localStorage.getItem("loginDetail"));
    return (
      <globalC.Provider
        value={{
          ...this.state,
          loginData: this.loginData
        }}
      >
        {this.props.children}
      </globalC.Provider>
    );
  }
}

最佳答案

问题

<BrowserRouter>
  <Switch>
    {authLogin ? (
      <>
        <Route path="/dashboard" component={Dashboard} exact />
        <Route exact path="/About" component={About} />
      </>
    ) : (
      <Route path="/" component={Login} exact />
    )}

    <Route component={PageNotFound} />
  </Switch>
</BrowserRouter>
Switch除了 Route 之外不处理任何渲染和 Render成分。如果您想像这样“嵌套”,那么您需要将每个都包装在通用路由中,但这完全没有必要。
您的登录组件也不处理重定向回最初访问的任何“主页”页面或私有(private)路由。
解决方案
创建一个 PrivateRoute消耗您的身份验证上下文的组件。
const PrivateRoute = (props) => {
  const location = useLocation();
  const { authLogin } = useContext(globalC);
  console.log("authLogin", authLogin);

  return authLogin ? (
    <Route {...props} />
  ) : (
    <Redirect
      to={{
        pathname: "/login",
        state: { from: location }
      }}
    />
  );
};
更新您的 Login组件来处理重定向回正在访问的原始路由。
export default function Login() {
  const location = useLocation();
  const history = useHistory();
  const { authLogin, loginData } = useContext(globalC);

  if (authLogin) {
    const { from } = location.state || { from: { pathname: "/" } };
    history.replace(from)
  }

  return (
    <div
      style={{ height: "100vh" }}
      className="d-flex justify-content-center align-items-center"
    >
      <button type="button" onClick={loginData} className="btn btn-primary">
        Login
      </button>
    </div>
  );
}
在“平面列表”中呈现所有路线
function Routes() {
  return (
    <BrowserRouter>
      <Switch>
        <PrivateRoute path="/dashboard" component={Dashboard} />
        <PrivateRoute path="/About" component={About} />
        <Route path="/login" component={Login} />
        <Route component={PageNotFound} />
      </Switch>
    </BrowserRouter>
  );
}
Edit how-to-create-a-protected-route-in-react-using-react-router-dom

关于reactjs - 如何创建 protected 路由?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66289122/

相关文章:

javascript - 如何使用嵌套路由向页面添加内容而不用 react-router-v4 删除先前路由的内容?

javascript - Reactjs 的 EventManager 抛出 "addHandler is not a function"

javascript - 让 API 在 JSX 中工作

animation - React 生命周期动画

javascript - DefaultRouter 组件中的嵌套路由

javascript - 页面未渲染;在react-router-dom中使用 protected 路由将 Prop 传递给子级时

javascript - import App from '../components/App' 和有什么区别?和 var App = require ('../components/App' );?

node.js - 是否可以在React App路径下托管Wordpress博客

javascript - React-Leaflet - 自定义 Pin,OnClick 链接到另一个页面

reactjs - React router dom为某些路由添加标题和仪表板