admin管理员组

文章数量:1327082

I'm trying to upgrade to react-router-dom v6 :

v5

In version 5 it works like a charm:

App.js

import Sidebar from "./ponents/sidebar/Sidebar";
import Topbar from "./ponents/topbar/Topbar";
import "./app.css";
import Home from "./pages/home/Home";
import {
  BrowserRouter as Router,
  Switch,
  Route,
} from "react-router-dom";
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";



function App() {

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

  return (
    <Router>
    <Switch>
      <Route path="/login">
        <Login />
      </Route>
      {admin && (
        <>
          <Topbar />
          <div className="container">
            <Sidebar />
            <Route exact path="/">
              <Home />
            </Route>
            <Route path="/users">
              <UserList />
            </Route>
            <Route path="/user/:userId">
              <User />
            </Route>
            <Route path="/newUser">
              <NewUser />
            </Route>
            <Route path="/products">
              <ProductList />
            </Route>
            <Route path="/product/:productId">
              <Product />
            </Route>
            <Route path="/newproduct">
              <NewProduct />
            </Route>
          </div>
        </>
      )}
    </Switch>
  </Router>
  );
}

export default App;

v6

When upgraded to v6 I changed my code to be like this:

<Routes>
  <Route path="/login" element={<Login />} />
  {admin && (
    <>
      <Route path="/" element={<Topbar />}/>
      <Route path="/" element={
        <>
          <div className="container">
            <Route index element={<Sidebar/>}/>
            <Route index element={<Home/>}/>
            <Route path="/users" element={<UserList />} />
            <Route path="/user/:userId" element={<User />} />
            <Route path="/newUser" element={<NewUser />} />
            <Route path="/productList" element={<ProductList />} />
            <Route path="/product/:productId" element={<Product />} /> 
            <Route path="/newProduct" element={<NewProduct />} />
          </div>
        </> 
      }
    </>
  )}
</Routes>

This is my css file for App.js

Notice: the Topbar ponent should be outside the div, and react router didn't recognize the ponents inside the as routes even without div, that means each ponent should have a unique path, I tried also two ponents with the same path like this:

<Route path="/" element = {<><Home/><Sidebar/><>}, but the css is not taking effect

.container {
  display: flex;
  margin-top: 50px;
}

It doesn't work. I tried different code and I searched a lot without finding any solution.

I'm trying to upgrade to react-router-dom v6 :

v5

In version 5 it works like a charm:

App.js

import Sidebar from "./ponents/sidebar/Sidebar";
import Topbar from "./ponents/topbar/Topbar";
import "./app.css";
import Home from "./pages/home/Home";
import {
  BrowserRouter as Router,
  Switch,
  Route,
} from "react-router-dom";
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";



function App() {

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

  return (
    <Router>
    <Switch>
      <Route path="/login">
        <Login />
      </Route>
      {admin && (
        <>
          <Topbar />
          <div className="container">
            <Sidebar />
            <Route exact path="/">
              <Home />
            </Route>
            <Route path="/users">
              <UserList />
            </Route>
            <Route path="/user/:userId">
              <User />
            </Route>
            <Route path="/newUser">
              <NewUser />
            </Route>
            <Route path="/products">
              <ProductList />
            </Route>
            <Route path="/product/:productId">
              <Product />
            </Route>
            <Route path="/newproduct">
              <NewProduct />
            </Route>
          </div>
        </>
      )}
    </Switch>
  </Router>
  );
}

export default App;

v6

When upgraded to v6 I changed my code to be like this:

<Routes>
  <Route path="/login" element={<Login />} />
  {admin && (
    <>
      <Route path="/" element={<Topbar />}/>
      <Route path="/" element={
        <>
          <div className="container">
            <Route index element={<Sidebar/>}/>
            <Route index element={<Home/>}/>
            <Route path="/users" element={<UserList />} />
            <Route path="/user/:userId" element={<User />} />
            <Route path="/newUser" element={<NewUser />} />
            <Route path="/productList" element={<ProductList />} />
            <Route path="/product/:productId" element={<Product />} /> 
            <Route path="/newProduct" element={<NewProduct />} />
          </div>
        </> 
      }
    </>
  )}
</Routes>

This is my css file for App.js

Notice: the Topbar ponent should be outside the div, and react router didn't recognize the ponents inside the as routes even without div, that means each ponent should have a unique path, I tried also two ponents with the same path like this:

<Route path="/" element = {<><Home/><Sidebar/><>}, but the css is not taking effect

.container {
  display: flex;
  margin-top: 50px;
}

It doesn't work. I tried different code and I searched a lot without finding any solution.

Share Improve this question edited Feb 20, 2022 at 6:19 Drew Reese 204k18 gold badges240 silver badges271 bronze badges asked Feb 19, 2022 at 13:52 chiheb loussifchiheb loussif 231 gold badge1 silver badge5 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Part of the issue is that you are rendering multiple identical paths, i.e. two "/" paths and two nested index paths. This won't work.

In react-router-dom v6 you can create what are called layout ponents. The layout ponents can render your headers and footers, sidebars, drawers, and general content layout elements, and importantly an Outlet ponent for the nested/wrapped Route ponents to be rendered into.

Example:

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

const AppLayout = ({ admin }) => admin ? (
  <>
    <Topbar />
    <div className="container">
      <Sidebar />
      <Outlet />
    </div>
  </>
) : null;

Render the layout ponent into a Route wrapping the routes you want to be rendered into the specific layout.

<Routes>
  <Route path="/login" element={<Login/>} />
  <Route element={<AppLayout admin={admin} />}>
    <Route index element={<Home />} />
    <Route path="/users" element={<UserList />} />
    <Route path="/user/:userId" element={<User />} />
    <Route path="/newUser" element={<NewUser />} />
    <Route path="/productList" element={<ProductList />} />
    <Route path="/product/:productId" element={<Product />} />
    <Route path="/newProduct" element={<NewProduct />} />
  </Route>
</Routes>

I will share working code from my project, hope this will help you.

Try to create a ponent layout that should look something like this:

// Layout.js
import React from "react";
import { NavBar } from "./SidebarNav";
export const Layout = ({ children }) => {
  return (
    <>
      <div className="block">
        <NavBar />
        <div className="w-full ">{children}</div>
      </div>
    </>
  );
};

and then create routes in a similar way:

// routes.js
import { Routes, Route } from "react-router-dom";
import { Layout } from "./layout/Layout";
import Home from "./pages/Home";
import { ItemList } from "./pages/ItemList";

const BaseRouter = () => (
  <>
    <Layout>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/item-list/" element={<ItemList />} />
      </Routes>
    </Layout>
  </>
);

export default BaseRouter;

Splitting routes into a separate file gives you more freedom and, above all, makes your code more accessible.

// App.js
import { BrowserRouter as Router } from "react-router-dom";
import BaseRouter from "./routes";

function App() {
  return (
    <Router>
      <BaseRouter />
    </Router>
  );
}

export default App;

本文标签: