在我的React应用程序的嵌套页面中使用React Router Dom v6路由时,URL发生变化,但组件未呈现

问题描述 投票:0回答:1

我有一个带有侧边栏和内容显示区域的主页,该区域将显示所选选项。 当我尝试单击侧边栏中的链接时,会出现问题,它不会更改内容显示部分中的任何内容,但 URL 会更改。 如果我在 App.js 中定义路由,则 Link 可以工作,但它会在新页面中打开组件,我希望它显示在 MainPage.js 中。

App.js:

import { useEffect, useState } from 'react';
import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; 

import LoginPage from './pages/LoginPage';
import MainPage from './pages/MainPage';
import SamplePage from './pages/SamplePage'


const App = () => {

    /** HOOKS */

    const [admin, setAdmin] = useState({name: "junaid"})
    // const [admin, setAdmin] = useState(null)

    // hook to see if admin is already logged in
    useEffect(() => {
        const loggedAdmin = window.localStorage.getItem('loggedProSkillzAdmin')
        if(loggedAdmin) {
            setAdmin(JSON.parse(loggedAdmin))
        }
    })

    return (
    <Router forcerefresh={true}>
    {/* <Navigate from="/" to={admin ? "/main" : "/login"} /> */}
        {/* <Navigate exact from="/" to="/main" /> */}
        <Routes>
            {admin === null ? (
                <Route path="*" element={<LoginPage setAdmin={setAdmin} />} />
            ) : (
                // If admin is logged in, navigate to MainPage
                <>
                    {/* Redirect from root to /main */}
                    <Route path="/" element={<Navigate to="/main" />} />
                    <Route path="/main/*" element={<MainPage />} />
                </>
            )}
            <Route path="*" element={<p>No Path Found</p>}/>
        </Routes>
    </Router>
        
    )

}

export default App;

MainPage.js:

import { Route, Routes, Link} from 'react-router-dom';

import { MdDashboard } from "react-icons/md";
import { IoIosSettings } from "react-icons/io";
import { FaUsers, FaUserAstronaut } from "react-icons/fa";

import Sidebar from "../components/Sidebar"
import SidebarItem from "../components/SidebarItem"
import SamplePage from './SamplePage';

const MainPage = () => {

    return (
        <div className='flex w-full h-full'>
            <Sidebar>
                <SidebarItem icon={<MdDashboard/>} text="Dashboard" path="dashboard" active={true}/>
                <SidebarItem icon={<FaUsers/>} text="Users" path="users" active={false}/>
                <SidebarItem icon={<FaUserAstronaut/>} text="Providers" path="providers" active={false}/>
                <SidebarItem icon={<IoIosSettings/>} text="Settings" path="settings" active={false}/>
            </Sidebar>
            <div className='w-full h-dvh bg-black'>
                <Routes>
                    <Route path="/main/dashboard" Component={<SamplePage title={"Dashboard"} index/>}/>
                    <Route path="/main/users" element={<SamplePage title={"Users"}/>}/>
                    <Route path="/main/providers" element={<SamplePage title={"Providers"}/>}/>
                    <Route path="/main/settings" element={<SamplePage title={"Settings"}/>}/>
                </Routes>
            </div>
        </div>
    )

}

export default MainPage

SidebarItem.js:

import { useContext } from "react"
import { SidebarContext } from "./Sidebar";
import { IoSettings } from "react-icons/io5";
import { Link } from "react-router-dom";

const SidebarItem = ({icon, text, path, active}) => {

    const { expanded } = useContext(SidebarContext)

    return (
        <>
        <Link to={`/main/${path}`} className={`
            relative flex items-center py-2 px-3 my-1
            font-medium rounded-md cursor-pointer
            ${active
                ? "bg-indigo-800 text-white"
                : "hover:text-white hover:bg-indigo-800 "
            }
        `}>
            <div>
                {icon}
            </div>
            <span className={`
                overflow-hidden transition-all
                ${expanded? "w-52 ml-3 visible":"w-0 invisible"}
            `}>
                {text}
            </span>

        </Link>
        </>
    )

}

export default SidebarItem

SamplePage.js:

const SamplePage = ({title}) => {

    console.log('Sample page works for ', title)

    return (
        <div className="bg-red-700 w-full h-full">
            {title}
        </div>
    )

}

export default SamplePage

Before Clicking the Link

After clicking the Link(notice url changes)

期望组件以某种方式在 MainPage.js 中呈现

javascript reactjs react-router-dom mern
1个回答
0
投票

问题

后代路由与父路由相对构建。

MainPage
在路径
"/main/*"
:

上渲染
<Route path="/main/*" element={<MainPage />} />

但是在其下行路线中包含另一个

"main"
路径段:

<Routes>
  <Route
    path="/main/dashboard"
    Component={<SamplePage title="Dashboard" index />}
  />
  <Route path="/main/users" element={<SamplePage title="Users" />} />
  <Route path="/main/providers" element={<SamplePage title="Providers" />} />
  <Route path="/main/settings" element={<SamplePage title="Settings" />} />
</Routes>

这意味着URL路径是实际上

"/main/main/dashboard"

解决方案

从下行路由中删除无关的

"main"
路径段。请务必正确使用
element
属性而不是
Component
,因为您没有使用数据路由器。

<Routes>
  <Route path="/dashboard" element={<SamplePage title="Dashboard" />} />
  <Route path="/users" element={<SamplePage title="Users" />} />
  <Route path="/providers" element={<SamplePage title="Providers" />} />
  <Route path="/settings" element={<SamplePage title="Settings" />} />
</Routes>
© www.soinside.com 2019 - 2024. All rights reserved.