#reactjs #react-hooks #react-router-dom
Вопрос:
Используя protected.route
, когда пользователь входит в систему, как мы можем заставить пользователя переходить на частные маршруты, такие как Dashboard
и ViewDetails
? Если он является пользователем администратора, то отобразите панель мониторинга, иначе просмотрите экран сведений. Может кто-нибудь, пожалуйста, посоветовать по этому поводу. Я добавил ссылку codesandbox для ссылки
на ссылку Codesandbox
https://codesandbox.io/s/tender-cerf-kss82?file=/src/components/Login.js
login.js
import { useState } from "react";
import { useHistory } from "react-router-dom";
const loginData = [
{ id: 1, email: "mat@test.com", password: "admin123", access: "admin" },
{ id: 1, email: "duo@test.com", password: "test123", access: "user" }
];
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const history = useHistory();
const onSubmit = (email, password) => {
if (
email === loginData[0].email amp;amp;
password === loginData[0].password amp;amp;
loginData[0].access === "admin"
) {
history.push("/");
} else {
history.push("/ViewDetails");
}
};
return (
<div>
Login Page <br></br>
<input
type="text"
name="email"
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="text"
name="password"
onChange={(e) => setPassword(e.target.value)}
/>
<input type="button" value="submit" onClick={onSubmit(email, password)} />
</div>
);
};
export default Login;
protected.route.js
import React from "react";
import { Route, Redirect } from "react-router-dom";
export const ProtectedRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={(props) => {
if (localStorage.getItem("loginEmail")) {
return <Component {...props} />;
} else {
return (
<>
<Redirect
to={{
pathname: "/login",
state: {
from: props.location
}
}}
/>
</>
);
}
}}
/>
);
};
App.js
import React, { useState } from "react";
import "./styles.css";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Dashboard from "./components/Dashboard.js";
import Login from "./components/Login.js";
import ViewDetails from "./components/ViewDetails.js";
import UserLoginProvider from "./components/UserLoginProvider.js";
import UserProfileProvider from "./components/UserProfileProvider.js";
import ProtectedRoute from "./components/protected.route.js";
import ReactDOM from "react-dom";
//var ReactDOM = require("react-dom");
const App = () => {
return (
<BrowserRouter>
<UserLoginProvider>
<UserProfileProvider>
<>
<Switch>
<ProtectedRoute exact path="/" component={Dashboard} />
<ProtectedRoute path="/ViewDetails" component={ViewDetails} />
<Route path="/Login" component={Login} />
</Switch>
</>
</UserProfileProvider>
</UserLoginProvider>
</BrowserRouter>
);
};
ReactDOM.render(
React.createElement(App, null),
document.getElementById("root")
);
export default App;
Комментарии:
1. Похоже, что ваш
ProtectedRoute
компонент не принимает во внимание какие-либо роли, когда речь заходит о защищенном доступе. Я также не вижу ничего, что помещало бы что-либо в localStorage с помощьюloginEmail
ключа. ВLogin
компоненте вы устанавливаетеaccess
ключ в localStorage. Я также вижу, что вы не используете состояние маршрута «от» для перенаправления пользователя обратно к тому, к чему он пытался получить доступ. Вы просто хотите перенаправить роли «администратора» на»/», а всех остальных-на «/viewDetails»? Немного неясно, какова ваша цель здесь.2. Да, когда пользователь с доступом «администратор» входит в систему, он должен перенаправляться на
/
панель мониторинга, а другие пользователи с доступом «пользователь» должны перенаправляться в /ViewDetails . Извините , я не уверен, как это правильно настроить в ссылке codesandbox3. Когда я ссылаюсь на один из ваших ответов на какой-то другой вопрос.. Я не был уверен, нужно ли мне создавать
Routes.js
компонент в моем проекте…4. Где вы хотите хранить свои пользовательские объекты? Похоже, вы еще не решили, хранить ли его в локальном хранилище или в любом из этих контекстов реакции.
5. Я счастлив, если он хранится в
localStorage
.
Ответ №1:
Вот пример предложения.
Обновите ProtectedRoute
компонент, чтобы получить role
поддержку доступа и условно отобразить Route
или Redirect
на основе любого role
, хранящегося в локальном хранилище. Если роль соответствует, верните ожидаемый маршрут, если он существует и не соответствует, затем перенаправьте домой, в противном случае перенаправьте на вход.
import { Route, Redirect } from "react-router-dom";
export const ProtectedRoute = ({ role, ...rest }) => {
const currentRole = JSON.parse(localStorage.getItem("role"));
if (currentRole === role) {
return <Route {...rest} />;
} else {
return (
<Redirect
to={{
pathname: currentRole ? "/" : "/login",
state: {
from: rest.location
}
}}
/>
);
}
};
Обновите Login
, чтобы сохранить access
роль аутентифицированного пользователя в локальном хранилище и перенаправить его обратно на путь, к которому он первоначально пытался получить доступ.
import { useHistory, useLocation } from "react-router-dom";
const Login = () => {
const history = useHistory();
const { state } = useLocation();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const onSubmit = (email, password) => {
const user = loginData.find(
(el) => el.email === email amp;amp; el.password === password
);
if (user) {
localStorage.setItem("role", JSON.stringify(user.access));
history.replace(state.from ?? "/");
} else {
console.error("no user match found!");
}
};
return (
<div>
....
</div>
);
};
Обновите защищенные маршруты, которые вы отображаете в своем App
.
const App = () => {
return (
<UserLoginProvider>
<UserProfileProvider>
<Switch>
<ProtectedRoute
role="admin"
path="/dashboard"
component={Dashboard}
/>
<ProtectedRoute
role="user"
path="/viewDetails"
component={ViewDetails}
/>
<Route path="/Login" component={Login} />
<Route>
.... home page with nav links, etc...
</Route>
</Switch>
</UserProfileProvider>
</UserLoginProvider>
);
};
Комментарии:
1. Потрясающее объяснение, приятель ! Если бы у меня был шанс, я мог бы проголосовать несколько раз.. ты мой спаситель ! Пожалуйста, опубликуйте несколько простых руководств по реагированию, я куплю их