使用react-router v6我需要一个导航栏永久存在,但无法在我的索引页面上同时显示<App/>和<Home/>,如何修复?

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

我正在使用 React 重建我的个人网站,并决定使用最新版本的 React-router-dom,我正在构建我的

App
组件来包含导航栏,然后在我想要显示的内容下方,例如
Home
Projects
。这在我的
/projects
路线上效果很好,但我似乎无法弄清楚如何在索引路线上渲染
App
Home
。有办法吗?这是我到目前为止所拥有的:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter, Link, Route, Routes } from 'react-router-dom';
// N.B. Routes replaces Switch as of V6

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
        // Using <App/> here keeps the navbar but doesn't display the homepage content
        <Route path="/" element={<App/>}>
        // But using <Home/> loses the navbar
        // Should I have my Navbar component in here somewhere or within the App?
          <Route path="projects" element={<Projects/>}/>
        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

function App() {
  // Help?
}

function Navbar() {
  return (
    <header> // Very crude example as I'm self-answering, in production I'll rename the component to Header
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/projects">Projects</Link>
          </li>
        </ul>
      </nav>
    </header>
}

function Home() {
  return <h1>Home</h1>
}

function Projects() {
  return <h1>Projects</h1>
}
reactjs react-router react-router-dom
3个回答
22
投票

如果您按照React-Router 6的教程使用了

createBrowserRouter
功能,并且不想更改为使用
<BrowserRouter>
,您可以进行以下转换:

开始

const router = createBrowserRouter([
    {
        path: "/", 
        element: <Root/>
    },
    {
        path: "/somePath", 
        element: <SomePath/>
    }
])

root.render(
    <div>
        <NavBar/>
        <RouterProvider router={router}/>
    </div>
)

导航栏显示错误

useHref() may be used only in the context of a <Router> component

转换

重构您的

createBrowserRouter
对象,以便您拥有带有导航栏组件的路径“/”和
<Outlet/>

import {Outlet} from "react-router-dom";

const router = createBrowserRouter([
    {
        path: "/", 
        element: <NavbarWrapper/>
        children:[
             {
                 path: "/", // yes, again
                 element: <Root/>
             },
             {
                 path: "/somePath",
                 element: <SomePath/>
             },
        ]
    }
])

function NavbarWrapper(){
    return (
    <div>
        <Navbar/>
        <Outlet/>
    </div>
    )
};

8
投票

应用程序可以无条件渲染

Navbar
,并将
Routes
组件和路由移动到
App
。索引文件将
App
渲染到
BrowserRouter

应用程序

function App() {
  return (
    <>
      <Navbar />
      <Routes>
        <Route path="/" element={<Home/>}>
        <Route path="projects" element={<Projects/>}/>
      </Routes>
    </>
  );
}

index.js

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

1
投票

首先,您的

App
组件如下所示:

function App() {
  return (
    <div className="App">
      <Navbar/>
      <main> // You don't *have* to wrap the Outlet in a main tag, but I am doing, to save having to remember to do it in each component
        <Outlet/>
      </main>
    </div>
  )
}

因此,现在您的

App
始终显示
Navbar
,并且插座将显示路线告诉它的任何页面。

好吧,这很好,但是当我想要渲染

App
并仍然保留导航栏时,它仍然意味着渲染
Home
,这真的能解决这个问题吗?

嗯,不是单独的。首先将该 Outlet 组件添加到从

react-router-dom
的导入中,否则我们将一事无成!

现在像这样调整你的路由:

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

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<App/>}>
          <Route index element={<Home/>}/>
          <Route path="projects" element={<Projects/>}/>
        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

看到带有

Route
组件的
Home
标签上如何有
index
标签吗?就是这样,这就是解决方案!现在,您的应用程序按应有的方式呈现,包括导航栏,并且其
Outlet
呈现索引路线上的
Home
元素。

© www.soinside.com 2019 - 2024. All rights reserved.