React: <Route exact path="/" /> 和 <Route path="/" /> 之间的区别是什么?

334

请有人解释一下以下两者间的区别:

<Route exact path="/" component={Home} />

<Route path="/" component={Home} />

我不知道 exact 的意思。


5
所有的回答都很好。但是有人可能会产生疑问,例如“为什么我们不能在所有路由中都使用<code>exact</code>呢?” 想象一下这样一个URL:<code>https://yourreactwebsite.com/getUsers/userId=?</code> 这是一个例子,用户的ID将动态地输入到URL中,因此我们无法在此处使用Router的<code>exact</code>属性。 - VIJAYKUMAR REDDY ALAVALA
8个回答

533

在这个例子中,没什么特别的。 exact 参数在你有多个名称相似的路径时发挥作用:

举个例子,假设我们有一个显示用户列表的Users组件。另外还有一个CreateUser组件,用于创建用户。 CreateUser 的url 应该嵌套在 Users 下面。所以我们的设置可能如下所示:

<Switch>
  <Route path="/users" component={Users} />
  <Route path="/users/create" component={CreateUser} />
</Switch>
现在的问题是,当我们访问http://app.com/users时,路由器将遍历所有已定义的路由并返回它找到的第一个匹配项。所以在这种情况下,它会先找到Users路由,然后返回它。没问题。
但是,如果我们访问http://app.com/users/create,它仍然会遍历所有已定义的路由并返回它找到的第一个匹配项。React路由器进行部分匹配,因此/users部分匹配/users/create,因此它将不正确地再次返回Users路由! exact参数禁用路径的部分匹配,确保只有在路径与当前URL完全匹配时才返回路由。
因此,在这种情况下,我们应该向我们的Users路由添加exact,这样它只能匹配/users
<Switch>
  <Route exact path="/users" component={Users} />
  <Route path="/users/create" component={CreateUser} />
</Switch>

文档详细解释了exact并且给出了其他示例。

2023年更新:正如用户smit-gabani所指出的:

新版本的React - v6不再支持exact。

根据官方文档中所述:

你不再需要在任何地方使用exact属性。这是因为所有路径默认都完全匹配。如果你想匹配更多的URL,因为你有子路由,请使用尾随的*,例如


18
"但是,如果我们访问http://app.com/users/create,它将再次遍历我们定义的所有路由,并返回找到的第一个匹配项。" - 实际上它会返回所有找到匹配(完全或部分)的路由。 @Chase DeAnda所描述的行为只会发生在<Route>被<Switch>标签包含的情况下。 - watsabitz
16
在我看来,“exact” 应该是默认选项。 - Alexander Derck
@YulioAlemanJimenez 最高级别的路由定义将始终获胜。因此,在根路径中,如果您有/admin/users/create,路由器将选择该路由,而不是嵌套在Admin组件中的/admin/users,因为Admin组件从未被渲染。 - Chase DeAnda
2
@ChaseDeAnda,我需要的恰恰相反。也许我应该在SO上编写一个新答案,以澄清我的情况并获得恰当的答案。 - Yulio Aleman Jimenez
非常感谢!我有嵌套路由,它们总是返回第一个路由,就像你说的那样。这个可以工作:<PrivateRoute path="/:unit/:department" component={Department} /> 但这个不行:<PrivateRoute path="/:unit/:department/main-admins" component={MainManagers} />。所以我在第一个路由中添加了 exact,然后它就可以工作了 :) - madsongr
显示剩余3条评论

33

简而言之,如果你为你的应用程序路由定义了多个路由,并使用Switch组件进行封装,就像这样;

<Switch>

  <Route exact path="/" component={Home} />
  <Route path="/detail" component={Detail} />

  <Route exact path="/functions" component={Functions} />
  <Route path="/functions/:functionName" component={FunctionDetails} />

</Switch>

然后,您需要将exact关键字放入路径也包含在另一个路径中的路由中。例如,主页路径/包含在所有路径中,因此它需要具有exact关键字以将其与以/开头的其他路径区分开来。原因与/functions路径类似。如果您想要使用另一条路由路径,如/functions-detail/functions/open-door,其中包含了/functions,则需要为/functions路由使用exact


4
实际上第二部分已经解释了。假设你有两个路由 /motor/motorbike,那么你需要在路径为 /motor 的路由中放置 exact。否则,/motor/motorbike 路由都会选择路径为 /motor 的组件。 - milkersarac

16

5
如果您为应用程序的路由定义了多个路由,并使用具有相似名称的 Routes 组件进行封装,则可能会出现无法预测的行为。
例如:
<Routes>
  <Route path="/users" component={Users} />
  <Route path="/users/create" component={CreateUser} />
</Routes>

当您访问路由时可能会出现一些错误。

/users/create

因为一旦React找到与regex user*匹配的根路径,它就会将您重定向到该路径,即/users。

像这样使用exact:

<Switch>
  <Route exact path="/users" component={Users} />
  <Route path="/users/create" component={CreateUser} />
</Switch>

React的新版本v6不再支持exact属性。

据其官方文档所述:

你不再需要在组件上使用exact属性,因为默认情况下所有路径都是精确匹配的。如果你想匹配更多的URL路径,比如有子路由,可以使用末尾的*通配符,例如:<Route path="users/*">


0

exact属性用于确保指定的路径与当前位置完全匹配。

路径 exact path="/":

<Route exact path="/" component={Home} />

在这种情况下,只有当路径完全匹配“/”时,Home组件才会被渲染,而不会对类似“/about”或“/contact”的路径进行渲染。
<Route path="/" component={Home} />

在这里,Home组件将不仅仅在精确路径“/”上渲染,还会在任何以“/”开头的路径上渲染。

-2
通过使用exact,您可以确保主页组件的内容不会出现在其他页面上。 没有使用exact的情况如下: 主页
位置:/
-----------------
homepage content
-----------------

第二页

位置:/second-page

-----------------
homepage content
-----------------
-----------------
second content
-----------------

==========================================

使用exact:

主页

位置:/

-----------------
homepage content
-----------------

第二页

位置:/second-page

-----------------
second content
-----------------

-7

请尝试这个。

       <Router>
          <div>
            <Route exact path="/" component={Home} />
            <Route path="/news" component={NewsFeed} />
          </div>
        </Router> 

            

4
请说明您提出的解决方案。 - ton

-8
最简短的答案是

请尝试这个。

<switch>
   <Route exact path="/" component={Home} />
   <Route path="/about" component={About} />
   <Route path="/shop" component={Shop} />
 </switch>

6
这几乎没有解释exact属性/属性的含义,因此肯定不是一个“答案”。您应该尝试回答实际提出的问题,而不是为一个您不确定原帖作者是否有的问题提供解决方案。 - Victor Zamanian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接