簡體   English   中英

反應路由器 v6 - 路由設置不正確

[英]react router v6 - routing is not getting set correctly

我想在我的反應應用程序中設置私有路由。 我創建了兩個組件。 ParivateRoute.js 和 ParivateRoute.js 我在 App.js 中導入這兩個組件。 我正在基於令牌設置私有路由,如果令牌存在,則設置私有路由,如果令牌是 null,則應設置公共路由。

我嘗試了一些代碼,設置了我的私有路由,但沒有設置我的公共路由。

我在公共路由中遇到這個問題,每當登錄表單(電子郵件和密碼)的兩個字段都是空的並且我點擊登錄按鈕時,路徑就像這樣http://localhost:3000/?email=&password=

雖然不應該如此。 我希望路徑是這樣的http://localhost:3000/每當我點擊登錄按鈕並且我的兩個字段(電子郵件和密碼)都是空的。

所以為此我不知道如何得到它。 我需要幫助以正確設置路由路徑。

請再提供一個幫助,我還想在多個組件上設置公共路由,例如登錄以及注冊。 那我該怎么做呢?

下面是我的代碼。

登錄.js

import React, { useState } from "react";
import { Form, Button } from "react-bootstrap";
import { useNavigate, Link } from "react-router-dom";
import RequireAuth from "./PrivateRoute";

const Login = ({ setTokenData }) => {
  const initialValues = {
    email: "",
    password: "",
  };

  const [userData, setUserData] = useState(initialValues);
  const authenticateUser = () => {
    const localInfo = JSON.parse(localStorage.getItem("signUpUser"));
    localInfo?.map((item) => {
      const userName = item.email;
      const userPassword = item.password;
      if (userName === userData.email && userPassword === userData.password) {
        console.log("success");
        const token = Math.random().toString(36).substr(2, 5);
        console.log("token is:", token);
        sessionStorage.setItem("token", JSON.stringify(token));
        setTokenData(token);
        toUsersTable();
      } else {
        console.log("failure");
        return false;
      }
    });
    setUserData(initialValues);
  };

  const navigateToUsersTable = useNavigate();
  const toUsersTable = () => {
    return navigateToUsersTable("/usersTable");
  };

  return (
    <>
      <Form className="loginForm">
        <Form.Group className="mb-3" controlId="formBasicEmail">
          <Form.Label>Email Address</Form.Label>
          <Form.Control
            type="email"
            placeholder="Enter email"
            value={userData.email}
            name="email"
            onChange={(e) =>
              setUserData({ ...userData, [e.target.name]: e.target.value })
            }
          />
        </Form.Group>
        <Form.Group className="mb-3" controlId="formBasicPassword">
          <Form.Label>Password</Form.Label>
          <Form.Control
            type="password"
            placeholder="Password"
            name="password"
            value={userData.password}
            onChange={(e) =>
              setUserData({ ...userData, [e.target.name]: e.target.value })
            }
          />
        </Form.Group>
        <Form.Group className="mb-3" controlId="formBasicCheckbox"></Form.Group>

        <Button
          variant="primary"
          type="submit"
          onClick={() => authenticateUser()}
        >
          Login
        </Button>

        <div className="txtToSignUpBtn">
          <span>OR</span> <Link to="/signUp">Click here to Register</Link>
        </div>
      </Form>
      <RequireAuth authenticateUser={authenticateUser} />
    </>
  );
};
export default Login;

PrivateRoute.js

import React from "react";
import { Route, Navigate, Routes } from "react-router-dom";
import Login from "./Login";
import UsersTable from "./UsersTable";

const PrivateRoute = ({ ...rest }) => {
  console.log("rest is", { ...rest });
  const token = JSON.parse(sessionStorage.getItem("token"));
  console.log(token);
  return (
    <Routes>
      <Route {...rest} element={token ? <UsersTable /> : <Navigate to="/" />} />
    </Routes>
  );
};

export default PrivateRoute;

公共路由.js

import React from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import Login from "./Login";

const PublicRoute = ({ ...rest }) => {
  const token = JSON.parse(sessionStorage.getItem("token"));
  return (
    <Routes>
      <Route
        {...rest}
        element={token ? <Navigate to="/usersTable" /> : <Login />}
      />
    </Routes>
  );
};
export default PublicRoute;

應用程序.js

import { Layout } from "antd";
import React from "react";
import Login from "./Login";
import SignUp from "./SignUp";
import UsersTable from "./UsersTable";
import PublicRoute from "./PublicRoute";
import PrivateRoute from "./PrivateRoute";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

const App = () => {
  return (
    <>
      <Layout>
        <Router>
          <Routes>
            <Route element={<SignUp />} exact path="/signUp" />
          </Routes>
          <PublicRoute element={<Login />} exact path="/" />
          <PrivateRoute element={<UsersTable />} exact path="/usersTable" />
        </Router>
      </Layout>
    </>
  );
};

export default App;

提前致謝。

react-router-dom中,自定義路由組件被淘汰、替換或更喜歡處理業務邏輯並渲染嵌套路由的children道具或Outlet或聲明性重定向的包裝器組件。

由於您詢問要在“私有”路由上放置多個組件,因此我建議使用Outlet實現。

const PrivateWrapper = () => {
  const token = JSON.parse(sessionStorage.getItem("token"));
  console.log(token);

  return token ? <Outlet /> : <Navigate to="/login" replace />;
};

const PublicWrapper = () => {
  const token = JSON.parse(sessionStorage.getItem("token"));

  return token ? <Navigate to="/" replace /> : <Outlet />;
};

...

const App = () => {
  return (
    <>
      <Layout>
        <Router>
          <Routes>
            <Route path="/" element={<div>Home Page</div>} />
            <Route path="/signUp" element={<SignUp />} />
            <Route element={<PublicWrapper />}>
              <Route path="/login" element={<Login />} />
              .... other public routes ....
            </Route>
            <Route element={<PrivateWrapper />}>
              <Route path="/usersTable" element={<UsersTable />} />
              .... other private routes ....
            </Route>
          </Routes>
        </Router>
      </Layout>
    </>
  );
};

我看不到您在哪里發出任何命令式導航,包括任何 queryString 參數,但據我所知,您並沒有阻止提交時的默認表單操作。 將提交處理程序移動到Form組件的onSubmit事件處理程序並在提交事件 object 上調用preventDefault

const authenticateUser = event => {
  event.preventDefault();
  ...
};

...

<Form className="loginForm" onSubmit={authenticateUser}>
  ...
  <Button
    variant="primary"
    type="submit"
  >
    Login
  </Button>
  ...
</Form>

當您單擊登錄按鈕時,url 更改為http://localhost:3000/?email=&password= bcuz 在您的表單上您沒有指定它應該使用的method ,默認值為GET 這就是為什么表單輸入出現在 url 中的原因,如果您不想在 url 中發送表單字段,則需要將方法設置為 post method="POST" 現在它們的字段不會在 url 中發送,但由於我們不是 90 年代,所以您不必這樣做。 您需要做的是防止默認行為。

從按鈕中刪除 onClickHandler 並將其添加到表單中

const onSubmit = event => {
event.preventDefault();
authenticateUser();
};

...
return(
<Form onSubmit={onSubmit}>
...
 <Button variant="primary" type="submit">Login</Button>

但不是onClick它是 onSubmit 確保防止默認

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM