我的项目中路由无法正常工作的原因是什么?

发布于 2025-02-09 20:22:00 字数 1652 浏览 1 评论 0原文

当我在地址之后键入“/创建”时,我希望它显示home组件。由于我不使用精确 prop。因为path ='/c'“/create”匹配,但它显示create component。它首先工作正常,当我从精确 prop中使用时,它可以按预期工作正常。我不知道为什么从第一个route中删除Exact后,它不按预期工作。

仅当我做:< outa path =“/” element = {< home/>}/>

注意:我将其用于运行服务器: npx json-server -watch数据/db.json -port 8000

请参阅codeSandBox上: https://codesandbox.io/s/epic-feather-uz2iur

这是我的路线部分:

function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <div className="content">
          <Routes>
            <Route path="/c" element={<Home />} />
            <Route path="/create" element={<Create />} />
          </Routes>
        </div>
      </div>
    </Router>
  );
}

它在我的webstorm上给出了相同的结果(react-router-dom版本5 ):

  <Router>
      <div className="App">
          <Navbar />
          <div className="content">
              <Switch>
                  <Route path="/">
                      <Home />
                  </Route>
                  <Route path="/create">
                      <Create />
                  </Route>
              </Switch>
          </div>
      </div>
  </Router>

When I type "/create" after the address, I expect it shows Home component. Since I don't use from exact prop. Because path='/c' matches with "/create", but it shows Create component. It first worked fine and when I used from exact prop it worked fine as expected. I don't know why it does not work as expected after I removed exact from the first Route.

It works fine only if I do: <Route path="/" element={<Home />} />

Note: I used this for run server: npx json-server --watch data/db.json --port 8000

See that on Codesandbox: https://codesandbox.io/s/epic-feather-uz2iur

It's the section of my Routes:

function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <div className="content">
          <Routes>
            <Route path="/c" element={<Home />} />
            <Route path="/create" element={<Create />} />
          </Routes>
        </div>
      </div>
    </Router>
  );
}

It gives the same result on my Webstorm(react-router-dom version 5):

  <Router>
      <div className="App">
          <Navbar />
          <div className="content">
              <Switch>
                  <Route path="/">
                      <Home />
                  </Route>
                  <Route path="/create">
                      <Create />
                  </Route>
              </Switch>
          </div>
      </div>
  </Router>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧人 2025-02-16 20:22:00

似乎问题是对路由路径匹配如何从react-router@5转换为react> react-router@6的误解。

在RRDV5中,路线路径更像是“路径前缀”,这意味着它的行为就像您描述的那样。 path =“/c”可以匹配 url路径以“/c”/c“”开始。当尝试具体或完全匹配某些路线时,这具有其特殊性。这就是为什么幼稚的开发人员会用eact prop prop pepper prop() )。

例如,您的V5版本,它需要使用Exact prop才能匹配“/c” 并渲染home component ,或者完全不匹配,因此可以匹配创建组件。

<Router>
  <div className="App">
    <Navbar />
    <div className="content">
      <Switch>
        <Route exact path="/c" component={Home} />
        <Route exact path="/create" component={Create} />
      </Switch>
    </div>
  </div>
</Router>

这是因为(a)路由匹配在V5中的工作方式,以及(b)switch组件渲染 唯一的方式路由重定向组件。路线路径顺序和特异性很重要!在几乎100%的用例中,您不需要精确的支架,只需正确订购路线,从 最具体的 最不具体的

相同的V5路由和切换,但正确订购:

<Router>
  <div className="App">
    <Navbar />
    <div className="content">
      <Switch>
        <Route path="/create" component={Create} />
        <Route path="/c" component={Home} />
      </Switch>
    </div>
  </div>
</Router>

请注意,“/c”无法匹配path =“/create”,并且匹配一直延续到找到它和匹配路径=“/c”

现在,在rrdv6中, 始终 完全匹配,因此exack ecker prop不再存在,因为它不需要。每条路由都使用路径排名系统,请参见等级路线。路径的特异性产生等级值,这用于匹配路由。路线订单现在无关紧要。

<Routes>
  {/* match & render when path is exactly "/c" */}
  <Route path="/c" element={<Home />} />

  {/* match & render when path is exactly "/create" */}
  <Route path="/create" element={<Create />} />
</Routes>

It seems the issue is a misunderstanding of how route path matching changed from react-router@5 to react-router@6.

In RRDv5 the route path was more of a "path prefix", meaning it behaved like you described. A path="/c" could match any URL path starting with "/c". This had its peculiarities when trying to specifically, or exactly, match certain routes. This is often why naive devs would pepper all their routes with the exact prop (because not understanding how matching worked).

For example, your v5 version, it would need to use the exact prop in order to match "/c" exactly and render the Home component, or not match exactly so the Create component could be matched.

<Router>
  <div className="App">
    <Navbar />
    <div className="content">
      <Switch>
        <Route exact path="/c" component={Home} />
        <Route exact path="/create" component={Create} />
      </Switch>
    </div>
  </div>
</Router>

This is because of (A) the way route matching works in v5, and (B) the way the Switch component renders only the first matching Route or Redirect component. The route path order and specificity matters! In almost 100% of the use cases you don't need the exact prop by simply ordering your routes correctly, from most specific to least specific.

The same v5 routes and switch, but ordered correctly:

<Router>
  <div className="App">
    <Navbar />
    <div className="content">
      <Switch>
        <Route path="/create" component={Create} />
        <Route path="/c" component={Home} />
      </Switch>
    </div>
  </div>
</Router>

Note now that "/c" can't match to path="/create" and matching continues down until it finds and matches path="/c".

In RRDv6 paths are now always exactly matched, so the exact prop no longer exists as it's not needed. Each route uses a path ranking system, see Ranking Routes. The specificity of the path yields a rank value and this is used to match a route. Route order is now irrelevant.

<Routes>
  {/* match & render when path is exactly "/c" */}
  <Route path="/c" element={<Home />} />

  {/* match & render when path is exactly "/create" */}
  <Route path="/create" element={<Create />} />
</Routes>
泪痕残 2025-02-16 20:22:00

使用React-Router-dom版本5您可以将switch*一起使用,并且应该

<Router>
  <div className="App">
    <Navbar />
    <div className="content"></div>
    <Switch>
      <Route path="/c*">
        <Home />
      </Route>
      <Route path="/create">
        <Create />
      </Route>
    </Switch>
  </div>
</Router>

根据文档

工作

a switch浏览其所有子女元素和渲染
第一个路径与当前URL匹配的第一个。使用任何一个
您有多个路线的时间,但是您只希望其中之一渲染
一次

工作示例

Using react-router-dom version 5 you can use Switch along with * and it should work

<Router>
  <div className="App">
    <Navbar />
    <div className="content"></div>
    <Switch>
      <Route path="/c*">
        <Home />
      </Route>
      <Route path="/create">
        <Create />
      </Route>
    </Switch>
  </div>
</Router>

According to documentation

A Switch looks through all its children elements and renders
the first one whose path matches the current URL. Use a any
time you have multiple routes, but you want only one of them to render
at a time

Working example

檐上三寸雪 2025-02-16 20:22:00

关于“精确” prop的V6发生了破坏的变化 - 它不再存在,默认情况下所有路径均为精确。

您可以在此处阅读更多信息:升级到v6

路线精确消失了。而是带有后代路线的路由(定义
在其他组件中)在他们的路径中使用尾随 *表示他们
匹配深度

There was a breaking change in v6 regarding "exact" prop - it does not exist anymore and all paths are by default exact.

You can read more here: upgrading to v6

Route exact is gone. Instead, routes with descendant routes (defined
in other components) use a trailing * in their path to indicate they
match deeply

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文