javascript 如何用react router实现嵌套路由

9vw9lbht  于 2023-05-15  发布在  Java
关注(0)|答案(2)|浏览(118)

我希望当用户在主页上导航到"/content"时呈现标题,当他们导航到"/content/about"时,呈现的About页面没有标题。这是不可能的。你能告诉我我的问题在哪里吗?
"/content":Header主页
"/content/about":关于没有标题的页面
App.js:

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Content from "./Content";

const ByHeader = () => {
  return (
    <>
      <div>Header</div>
      <Content />
    </>
  );
};

export default function App() {
  return (
    <Router>
      <Switch>
        <Route path="/content">
          <ByHeader />
        </Route>
        <Route path="/content/*">
          <Content />
        </Route>
      </Switch>
    </Router>
  );
}

import React from "react";
import { Route } from "react-router-dom";

const Home = () => {
  return <div>Home page by header</div>;
};

const About = () => {
  return <div>About page without header</div>;
};

const Content = () => {
  return (
    <>
      <Route path="/" exact>
        <Home />
      </Route>
      <Route path="/about" exact>
        <About />
      </Route>
    </>
  );
};

export default Content;

cosesandbox

flseospp

flseospp1#

Router.js

const PrivateRoute = ({ children }) => {
  const navigate = useNavigate();

  React.useEffect(() => {
    // here you should have IsAuthorized in your services 
    // to check if user is authorized or not
    if (!IsAuthorized) {
      navigate('/image');
    }
  }, []);

  return children;
};

const Image =()=> {
  return (
    <div>
      <header> your header goes here </header>
      <div>Image page</div>
    </div>
  )
}

const ImageAbout =()=> {
  return (
    <div>
      <header> don't include header </header>
      <div>Image page</div>
    </div>
  )
}

export const  RootRouter = () => {

return (
    <Routes>
      <Route
        path="/"
        element={
          <PrivateRoute>
            <RootPage />
          </PrivateRoute>
        }
      >
        <Route path="/image/about" element={<Image/>} />
        <Route path="/image/about" element={<ImageAbout />} />
    </Route>
    </Routes>
}

用途

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <BrowserRouter>
      <RootRouter />
    </BrowserRouter>
  </React.StrictMode>
);
ttvkxqim

ttvkxqim2#

问题

代码现在不工作,原因如下:
1.您正在将所有路由(包括呈现标头的路由)呈现到一个Switch组件中。
1.呈现header的Switch中的路由首先列出,一旦匹配,其余路由将被忽略,无论匹配与否。

  1. Content组件使用的绝对路径不包括父路由的"content"路径段,因此这些路由是不可匹配的。

建议方案

我的建议是将content组件更多地视为一个布局组件,它无条件地呈现路由上的标题,并在Switch组件中有条件地呈现路由内容。
请记住,所有Route组件都是***包含***匹配和呈现的,例如:匹配的任何内容都将被渲染,而Switch组件内渲染的Route组件则***排他地***匹配和渲染,例如呈现第一匹配RouteRedirect
还要记住,当使用Switch或向Route组件传递路径数组时,路径顺序和特定性很重要。按照路径特异性的***逆***顺序对路由/路径进行排序。例如,"/content/about""/content"更具体,"/"更具体,因此这应该是尝试匹配时的路径顺序。
以下是我的建议的实施情况。
示例:

const Content = () => {
  const { path } = useRouteMatch();
  return (
    <>
      <Route path={[path]} exact component={Header} />
      <Switch>
        <Route path={`${path}/about`} component={About} />
        <Route path={path} component={Home} />
      </Switch>
    </>
  );
};

父/应用程序组件

<Route path="/content" component={Content} />

Demo

相关问题