【问题标题】:React component with react-router inside an app with react-router使用 react-router 在应用程序中使用 react-router 反应组件
【发布时间】:2021-06-14 13:37:14
【问题描述】:

我正在开发一个带有自己的 react-router-dom 的 react 组件,以便能够处理像 /post/post/123 这样的路径。

我需要将此组件打包为 npm 模块,以便它可以嵌入到另一个具有自己的 react-router-dom 的 React 应用程序中。

托管应用:

<Router>
  <Switch>
    <Route path="/posts" exact={true}>
      <Blog />
    </Route>
  </Switch>
</Router

在博客组件中:

<Router basename="/posts">
   <Switch>
     <Route path="/">
       <p>Display all posts</p>
     </Route>
     <Route path="/post/:id">
       <p>Display details for post with id</p>
     </Route>
   </Switch>
</Router>

当我访问/posts 路径时,我收到Display all posts 消息。但是,当我访问 /post/123 路径时,我看不到 Display details for post with id 消息。

如何让内部路由器路径与外部路由器一起使用?

【问题讨论】:

  • 如果您希望在其子项中匹配非精确路由,则托管应用程序中的 Route 不能将 exact 属性设置为 true。
  • 当我在托管应用程序中删除 exact 属性并访问 /posts/post/:id 路由时,我得到了 Display all posts 文本。似乎问题是内部路由器无法检测到网址更改

标签: reactjs react-router


【解决方案1】:

您缺少确切的关键字

 <Router basename="/posts">
       <Switch>
         <Route exact path="/">
           <p>Display all posts</p>
         </Route>
         <Route exact path="/post/:id">
           <p>Display details for post with id</p>
         </Route>
       </Switch>
    </Router>

【讨论】:

  • 不 - 添加 exact 不会改变任何东西。单击帖子以查看帖子详细信息确实会更改浏览器中的 url,但不会呈现详细信息。刷新浏览器然后呈现主应用的 404 页面
【解决方案2】:

这是完整的解决方案:尝试这样做:

如果您在“路由器”中使用 basename,请这样做

const BlogPage = () =>{
    return(
        <Router basename='/posts'>
            <Switch>
                <Route path='/posts' exact>
                    <p>Display All Posts </p>
                </Route>
                <Route path='/:id' exact>
                    <p>Display Post with Id </p>
                </Route>
            </Switch>
        </Router>
    )
}

或者,如果您在不使用 basename 的情况下使用路由器,那么它应该是这样的:

const BlogPage = () =>{
    return(
        <Router>
            <Switch>
                <Route path='/posts' exact>
                    <p>Display All Posts </p>
                </Route>
                <Route path='/posts/:id/' exact>
                    <p>Display Post with Id </p>
                </Route>
            </Switch>
        </Router>
    )
}

看看两者的区别

【讨论】:

  • 这和他们的不一样。它们有一个“posts”的基本名称,然后子路由器有“post” - 单数。第一个例子也会产生“posts/posts”,这也不是他们所拥有的。
【解决方案3】:

对于遇到此问题的任何人 - 我通过将 history 传递给两个路由器来解决它:

主应用:

import { BrowserRouter as Router, Route } from 'react-router-dom';

const App = () => {
  return (
    <Router>
      <Switch>
        <Route path="/posts">
          <Blog />
        </Route>
      </Switch>
    </Router>
  );
}

博客组件:

import { BrowserRouter as Router, Route } from 'react-router-dom';

const Blog = () => {
  return (
    <Router basename="/posts">
      <Switch>
        <Route path="/" exact>
          <p>Display all posts</p>
        </Route>
        <Route path="/post/:id" exact>
          <p>Display details for post with id</p>
        </Route>
      </Switch>
    </Router>
  )
}

【讨论】:

  • useHistory 仅在有父 Router 来创建该历史记录时才能将 history 提供给子路由器。如果 必须 成为父路由器才能使其工作,我的问题是 - 为什么有子路由器?除了所有路由前缀的basename 之外,它还提供什么?我只会使用嵌套的Switch 并从Blog 中完全删除Router
  • 问题在于 Blog 组件是作为 npm 包添加到 App 的外部组件。由于博客组件包含链接(在帖子组件中链接到帖子详细信息页面),它必须包含Router - 否则我会收到“不变违规”错误。你是正确的想法 - 父母 Router 需要 history 道具而不是孩子 - 我相应地更新了我的答案
  • 这不会在父级中引发错误?
  • @BrianThompson 你是对的 - 相应地更新了我的答案。谢谢
猜你喜欢
  • 2018-11-12
  • 2018-09-11
  • 2016-04-19
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
  • 2015-06-26
  • 2019-08-07
  • 2016-01-27
相关资源
最近更新 更多