[英]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.