我正在尝试使用react-router-dom来处理我的React应用程序导航。我在使用标准
useNavigate
函数时遇到了一些问题,因为我的标头组件位于路由器之外。
我正在尝试重组应用程序以将我的标题移动到路由器内,但是当我这样做时,标题不会出现。
目前我的标题呈现在我的index.js 文件中:
<AppProvider>
<Header />
<AppRoutes />
</AppProvider>
AppRoutes
使用createBrowserRouter
:
import React from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from "./App";
import { Header } from "./Header";
import { AppLayout } from "./AppLayout";
import { AccountHome } from "./pages/AccountHome/AccountHome";
const router = createBrowserRouter([
{
path: "/",
element: <AppLayout />,
},
{ path: "/account", element: <AccountHome /> },
]);
export const AppRoutes = ({ auth }) => {
return <RouterProvider router={router} />;
};
并且
AppLayout
使用 Outlet
:
export const AppLayout = () => {
const {
isAuthenticated,
isPricingModalOpen,
pricingOptions,
setIsPricingModalOpen,
} = useContext(AppContext);
return (
<>
<PricingModal
isPricingModalOpen={isPricingModalOpen}
pricingOptions={pricingOptions}
setIsPricingModalOpen={setIsPricingModalOpen}
/>
{isAuthenticated ? <HomePage /> : <LandingPage />}
<Outlet />
</>
);
};
我尝试将标题移动到我的
AppLayout
中,但标题没有出现在 AccountHome
上
我认为您需要切换到更具可读性和基于组件的结构。 我用这个
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
,它对我来说效果很好。
我正在向您分享我的组件,希望您能理解这个周期。
根文件App.jsx
import 'react-toastify/dist/ReactToastify.css'
**import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'**
import { AuthProvider } from './context/AuthProvider'
import { AdminAuthProvider } from './context/AdminAuthProvider'
import { ToastContainer } from 'react-toastify'
import Signup from './pages/Signup'
import Verification from './pages/Verification'
import Welcome from './pages/Welcome'
import NotFound from './pages/NotFound'
import Login from './pages/Login'
import ProtectedRoute from './ProtectedRoute'
import AdminRoutes from './routes/AdminRoutes'
const App = () => {
return (
<AuthProvider>
<AdminAuthProvider>
<Router>
<ToastContainer />
<Routes>
<Route path="*" element={<NotFound />} />
<Route path="/" element={<Signup />} />
<Route path="/signup" element={<Signup />} />
<Route path="/verify" element={<Verification />} />
<Route path="/welcome" element={<Welcome />} />
<Route path="/login" element={<Login />} />
<Route
path="/admin/*"
element={
<ProtectedRoute roles={['admin']}>
<AdminRoutes />
</ProtectedRoute>
}
/>
<Route path="/unauthorized" element={<div>Unauthorized Access</div>} />
</Routes>
</Router>
</AdminAuthProvider>
</AuthProvider>
)
}
export default App
在根目录下创建一个目录
/routes
,然后为全局保护路由创建一个组件:root/routes/ProtectedRoute.jsx
我有这个代码,根据您的用例进行调整
import { Navigate } from 'react-router-dom'
import { useAdminAuth } from '../context/AdminAuthProvider'
const ProtectedRoute = ({ roles, children }) => {
const { admin } = useAdminAuth();
if (!admin) {
return <Navigate to="/login" />;
}
if (roles && !roles.includes(admin.role)) {
return <Navigate to="/unauthorized" />;
}
return children;
};
export default ProtectedRoute
如您所见,我只有管理内容需要保护。 因此,在
AdminRoutes.jsx
目录中创建另一个组件
/routes
以下是我的代码,您可以根据您的用例调整代码
import { Routes, Route } from 'react-router-dom'
import ProtectedRoute from './ProtectedRoute'
import Dashboard from '../pages/admin/Dashboard'
import Referral from '../pages/admin/Referrals'
import NotFound from '../pages/admin/NotFound'
const AdminRoutes = () => {
return (
<ProtectedRoute roles={['admin']}>
<Routes>
<Route path="*" element={<NotFound />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="referrals" element={<Referral />} />
</Routes>
</ProtectedRoute>
)
}
export default AdminRoutes
注意上面,我再次定义了路由,同时我也在应用程序的入口文件中定义了它们
App.jsx
。以上路线仅供管理员使用。
您可以忽略任何您不喜欢的额外导入。但我想,这样你就能完成它。
您可以将您的组件单独放置在您需要的所有组件中。
为了解决方案,我正在分享我的
root/pages/admin/dashboard
组件,以便您可以更清楚地看到渲染
import V1 from '../../assets/v1.png'
import V2 from '../../assets/v2.png'
import { useAdminAuth } from "../../context/AdminAuthProvider"
import { Link, useNavigate } from 'react-router-dom';
import { motion } from 'framer-motion';
import { MdLogout } from 'react-icons/md';
import Header from '../../partials/Header';
import Footer from '../../partials/Footer';
import PaginatedItems from '../../components/Pagination';
const Dashboard = () => {
const { admin, adminLogout } = useAdminAuth();
const navigate = useNavigate();
document.title = `YourWebsite | ${admin?.role.charAt(0).toUpperCase() + admin?.role.slice(1) || 'Admin'} | Dashboard`;
if (!admin) {
navigate('/login');
}
return (
<>
<Header />
<div className="inner-app-container">
<motion.img
src={V1}
className="left-curve"
alt="Left curve decoration"
/>
<motion.img
src={V2}
className="bottom-right-shape"
alt="Bottom right shape decoration"
/>
<motion.div
className="inner-app-box"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1, ease: "easeIn" }}
>
<div className="inner-app-box-header">
<h1>
<span>Dashboard <Link className="link" to="/admin/referrals">Referrals</Link></span>
<div className="user">
Hi! {admin?.name}
<a className="logout-button" onClick={adminLogout}>
<MdLogout size={20} />
</a>
</div>
</h1>
<h3>Users raw data</h3>
</div>
<PaginatedItems itemsPerPage={10} />
</motion.div>
<Footer />
</div>
</>
)
}
export default Dashboard
请告诉我这是否对您有帮助,或者您是否需要与此解决方案相关的任何特定内容。
致敬,