You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Router v6 升级问题:同一路径下如何在div内外渲染多个组件

Fixing React Router v6 Layout & Routing Issues After Upgrade

I see exactly where you're hitting snags with the v6 upgrade—React Router v6 completely changed how nested routing and layout composition works compared to v5. Let's break down the problem and fix it step by step.

The Core Issue in Your Current v6 Code

In v6, <Route> components can only be direct children of <Routes> or other <Route> components—they won't work if nested inside a <div> or regular React component. Also, your approach to rendering multiple components at the same path was missing the proper layout structure that keeps your CSS working as expected.

The Right Approach: Nested Routes with <Outlet>

React Router v6 uses layout routes and the <Outlet> component to handle shared UI (like your Topbar and Sidebar) across multiple routes. Here's how to adapt your code to match your original v5 behavior perfectly:

Step 1: Create an Admin Layout Component

First, make a dedicated layout component that renders your shared UI and uses <Outlet> to inject the page-specific content:

import { Outlet } from 'react-router-dom';
import Topbar from "./components/topbar/Topbar";
import Sidebar from "./components/sidebar/Sidebar";

const AdminLayout = () => {
  return (
    <>
      <Topbar />
      <div className="container">
        <Sidebar />
        {/* Outlet will render the current matched child route's element */}
        <Outlet />
      </div>
    </>
  );
};

Step 2: Update Your App.js Routing

Now use this layout in your routes. All admin-protected routes will be nested under the layout route, so they inherit the Topbar and Sidebar automatically:

import { BrowserRouter as Router, Routes, Route, Outlet } from "react-router-dom";
import Home from "./pages/home/Home";
import UserList from "./pages/userList/UserList";
import User from "./pages/user/User";
import NewUser from "./pages/newUser/NewUser";
import ProductList from "./pages/productList/ProductList";
import Product from "./pages/product/Product";
import NewProduct from "./pages/newProduct/NewProduct";
import Login from "./pages/login/Login";
import Topbar from "./components/topbar/Topbar";
import Sidebar from "./components/sidebar/Sidebar";

// Define the admin layout here (or move to a separate file for organization)
const AdminLayout = () => {
  return (
    <>
      <Topbar />
      <div className="container">
        <Sidebar />
        <Outlet />
      </div>
    </>
  );
};

function App() {
  const admin = JSON.parse(JSON.parse(localStorage.getItem("persist:root"))?.user || "{}")?.currentUser?.isAdmin ;

  return (
    <Router>
      <Routes>
        {/* Public login route */}
        <Route path="/login" element={<Login />} />

        {/* Admin-protected routes with shared layout */}
        {admin && (
          <Route path="/" element={<AdminLayout />}>
            {/* Default route (matches exactly "/") */}
            <Route index element={<Home />} />
            {/* User management routes */}
            <Route path="/users" element={<UserList />} />
            <Route path="/user/:userId" element={<User />} />
            <Route path="/newUser" element={<NewUser />} />
            {/* Product management routes (fixed path to match v5's "/products" instead of "/productList") */}
            <Route path="/products" element={<ProductList />} />
            <Route path="/product/:productId" element={<Product />} />
            <Route path="/newProduct" element={<NewProduct />} />
          </Route>
        )}
      </Routes>
    </Router>
  );
}

export default App;

Why This Works

  • Layout Reusability: The AdminLayout component handles rendering the Topbar and Sidebar once, and <Outlet> takes care of inserting the active page component. This keeps your code DRY and matches your v5 structure exactly.
  • CSS Compatibility: Your .container class's display: flex will work correctly because the Sidebar and Outlet (which holds the page content) are direct children of the container div—just like in your v5 code.
  • Valid Routing Structure: All <Route> components are either direct children of <Routes> or nested under another <Route>, which is a requirement for React Router v6 to recognize and process them.

Quick Notes

  • I fixed the product list path from /productList back to /products to match your v5 code—adjust this if you intentionally changed the path structure.
  • If you want to handle unauthorized access to admin routes (when admin is false), you can add a redirect to the login page or an error route, but that's an optional extra for your current issue.

内容的提问来源于stack exchange,提问作者chiheb loussif

火山引擎 最新活动