Помощь Я использую защищенный маршрут в своем приложении React. Но это не работает. Все остальные элементы работают, но когда я дошел до «/account», весь экран стал белым. Это мой код. Мне будет очень полезно, если вы дадите этот ответ. Спасибо :)
Код защищенного маршрута:
import React, { Fragment } from 'react';
import { useSelector } from 'react-redux';
import { Route, Routes, redirect } from 'react-router-dom';
const ProtectedRoute = ({ element: Element, ...rest }) => {
const { loading, isAuthenticated, user } = useSelector(state => state.user);
return (
<Fragment>
{!loading &&
(<Routes>
<Route
{...rest}
render = {(props) => {
if (!isAuthenticated) {
return redirect("/login")
}
return <Element {...props} />
}}
/>
</Routes>
)}
</Fragment>
)
}
export default ProtectedRoute;
Я использую ProtectedRoute.js в App.js. Вот код. Код приложения.js:
import React from 'react';
import {BrowserRouter as Router,Route,Routes} from "react-router-dom";
import './App.css';
import Header from "./component/layout/Header/Header.js";
import webFont from "webfontloader";
import Footer from './component/layout/Footer/Footer';
import Home from "./component/Home/Home.js";
import ProductDetails from "./component/Product/ProductDetails.js";
import Products from "./component/Product/Products.js";
import Search from "./component/Product/Search.js";
import LoginSignUp from './component/User/LoginSignUp';
import store from "./store";
import { loadUser } from './action/userAction';
import UserOption from "./component/layout/Header/UserOption.js";
import { useSelector } from 'react-redux';
import Profile from "./component/User/Profile.js"
import ProtectedRoute from './component/Route/ProtectedRoute';
function App() {
const {isAuthenticated, user} = useSelector(state => state.user)
React.useEffect(() => {
webFont.load({
google:{
families:["Roboto","Droid Sans","Chilanka"]
},
});
store.dispatch(loadUser())
}, [])
return (
<Router>
<Header />
{isAuthenticated && <UserOption user = {user} />}
<Routes>
<Route path = "/" element = {<Home />} />
<Route path = "/product/:id" element = {<ProductDetails />} />
<Route path = "/products" element = {<Products />} />
<Route path = "/products/:keyword" element = {<Products />} />
<Route path = "/search" element = {<Search />} />
<Route path = "/account" element = { <ProtectedRoute> <Profile /> </ProtectedRoute> } />
<Route path = "/login" element = {<LoginSignUp />} />
</Routes>
<Footer />
</Router>
);
}
export default App;



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не уверен, но вы не передали какой-либо реквизит "элемента" вашему компоненту ProtectedRoute. Вы передаете компонент Profile как дочерние элементы, поэтому попробуйте визуализировать дочерние элементы вместо элемента в ProtectedRoute, если хотите, чтобы ваш код работал так.
Я считаю, что вы, возможно, захотите не вкладывать эти маршруты, поэтому вы также можете попробовать использовать ProtectedRoute в качестве маршрута в своем маршрутизаторе, я говорю о чем-то вроде этого.
<Routes>
...
<ProtectedRoute path = "/account" element = {<Profile />} />
...
</Routes>
ОБНОВИТЬ
Это может показать вам эту ошибку, потому что ваш маршрут отображается условно, поэтому попробуйте обработать состояние загрузки каким-то другим способом, может быть, что-то вроде этого
return (
<Route
{...rest}
render = {(props) => {
if (!isAuthenticated) {
return redirect("/login")
}
if (loading) {
return <LoadingComponent />
}
return <Element {...props} />
}}
/>
)
я обновлю свой ответ
OP использует react-router@6, а не v5, поэтому нет поддержки функции render, а ProtectedRoute нельзя визуализировать непосредственно в компоненте Routes.
@DrewReese Спасибо за эту информацию. Не могли бы вы помочь мне с кодом?
@SayedulKarim Помогает ли вам отмеченный дубликат?
В вашем App.js вы можете объявить маршрут protected следующим образом.
<Route path = "/account" element = { <ProtectedRoute /> } >
<Route path = "/account" element = { <Profile /> } >
</Route>
Вы можете использовать Outlet из react-router v6 для прохождения Component
const ProtectedRoute = ({ element: Element, ...rest }) => {
const { loading, isAuthenticated, user } = useSelector(state => state.user);
if (loading) {
return <h2>Loading...</h2>
}
return isAuthenticated ? <Outlet /> : <Navigate to = "/login" />;
}
Канеки Большое спасибо. Первое решение <Route path = "/account" element = { <ProtectedRoute /> } > <Route path = "/account" element = { <Profile /> } /> </Route> сработало. Я имею в виду, что теперь я могу видеть страницу «./account». Но макет или компонент внутри страницы, я имею в виду внутри «./account», не загружается.
Не могли бы вы проверить мой код ProtectedRoute и сказать мне более четко, где я должен использовать Outlet, Navigate или Redirect? Спасибо
вы получаете какую-либо ошибку в консоли браузера?
Да. Это то, что я получаю в консоли "utils.ts:716 Вы отобразили потомок <Routes> (или вызвали useRoutes()) в "/account" (в разделе <Route path = "/account">), но путь родительского маршрута не имеет конечного "". Это означает, что при более глубоком переходе родительский маршрут больше не будет совпадать, и поэтому дочерние маршруты никогда не будут отображаться. Пожалуйста, измените родительский <Route path = "/account"> на <Route path = "/account/"> . "
В сообщении об ошибке utils.ts:716 You rendered descendant <Routes> (or called useRoutes()) at "/account" (under <Route path = "/account">) but the parent route path has no trailing ясно, что вы используете <Routes></Routes> в компоненте Profile, вы также должны поделиться его кодом.
Я не использую маршруты в Profile.js. Это просто обычные теги Fragment,div,h1,p и т.д.
@ Сайедул Карим.
У меня есть лучший и более лаконичный способ для этого. Пример кода ниже.
<Routes>
<Route element = {<App />}>
{isAuthenticated ? (
<>
<Route path = "/*" element = {<PrivateRoutes />} />
<Route
index
element = {<Navigate to = "/account" />}
/>
</>
) : (
<>
<Route path = "auth/*" element = {<AuthPage />} />
<Route path = "*" element = {<Navigate to = "/auth" />} />
</>
)}
</Route>
</Routes>
Таким образом, вам не нужно создавать какой-либо частный компонент, вместо этого просто создайте компонент для частных маршрутов, где маршруты определены.
Компонент PrivateRoutes будет таким
<Routes>
<Route>
{/* Redirect to account page after successful login */}
{/* Pages */}
<Route path = "auth/*" element = {<Navigate to = "/account" />} />
<Route path = "account" element = {<Account />} />
</Routes>
Если возникнут какие-либо вопросы, не стесняйтесь спрашивать....
Muhiq, Большое спасибо за ваш ответ, братан. Это четкий код. Но меня, как новичка, это немного смущает. Вот почему я предпочитаю использовать метод privet. Но, конечно, когда я стану таким же экспертом, как вы, я смогу использовать этот метод.
Хорошо, для этого у меня также есть простой код для частных и общедоступных маршрутов, в котором я использовал Outlet из react-router-dom. Вот ссылка на изображение , состоящее из фрагмента маршрутизации , пожалуйста, обратитесь к этому.
Спасибо за ответ, Олег. Я очень ценю это. Да, я понимаю, что использовал так же, как вы дали ответ. В нем говорится, что «ProtectedRoute» не является элементом «Маршруты». Я имею в виду, что я должен использовать «Маршрут» как элемент внутри «Маршрутов».