React Router Switch 和确切路径
React Router Switch and exact path
我已阅读有关 react-router Switch
的文档
我理解Switch和Route的定义
但还是有些地方没看懂
如果我只想选择一个路由来渲染,我们可以像这样使用 Switch
<Switch>
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
</Switch>
我无法理解的一点是,我可以在没有开关的情况下获得相同的效果
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
那我们为什么要用Switch呢?什么时候需要用到Switch?
我发现了一个需要使用Switch的情况
如果我想在没有路径匹配时渲染特定组件
我们需要像这样在 Switch 中包装 Route
<Switch>
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route component={SpecificComponent} />
</Switch>
我说得对吗?
虽然在您的情况下您可以使用 exact 获得相同的效果,但情况可能并非总是如此。但是,如果您的其中一个路线包含嵌套路线,如果您在顶层有确切的路线,则无法使用嵌套路线。
Switch
在上述情况下达到了目的,因为它只呈现第一个匹配项
例如,
假设 Home 路线包含嵌套路线,例如
const Home = (props) => (
<div>
<Route path="/dashboard" component={Dashboard}/>
<Route path="/layout" component={Layout}/>
</div>
)
所以现在如果你写
<Route exact path="/" component={Home} />
当您访问 /dashboard
时。 Dashboard
组件无法呈现,因为没有路由与顶层的 /dashboard
匹配。
为了使示例 运行 正确,您可以使用 Switch
并重新排序路由,以便作为其他路径前缀的路径在末尾
<Switch>
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route path="/" component={Home} />
</Switch>
基本上,"exact" 关键字都有相同的用途。 (注意:使用检查当前 URL 是否以此路径开头的匹配算法。)但是当我们使用 时,路由声明或特异性的顺序很重要。需要在顶部添加更具体的 Route。你的情况
<Switch>
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route exact path="/" component={Home} />
</Switch>
在"exact"的情况下,当你传递"exact"时,只有路径完全匹配才会匹配这条路由。在您的情况下,主路径设置为准确。
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
让我列出Route
、exact
和Switch
的不同特征:
Route
进行部分匹配。 Route 的路径包含匹配(匹配很多)。
exact
删除部分匹配。它可能匹配多个路由,以防我们在路由中使用通配符。
Switch
只渲染第一个匹配的路由。 Switch
路径完全匹配(只匹配一个)。
为了详细解释,我想说明路由匹配在有和没有 exact
的情况下是如何工作的。假设我们有以下代码并且我们没有使用 exact
.
因此,如果我们访问 /pagetwo
URL,Route
将进行部分匹配并呈现两条路线。让我们看看它是如何发生的。在下图中,我们正在查看地址栏和我们导航到的路径(提取的路径)以及正在匹配的路由。因此,Route
将在 extractedPath.contains(path-in-our-Route-declaration)
评估为真时呈现路线。
希望阐明 Route
在幕后是如何工作的。为了避免这种部分匹配,我们使用 exact
。使用 exact
解决问题,直到我们遇到一些特殊情况。假设我们有两条路线:
/users/create
/users/*
(路由中的通配符)。
在上述情况下,exact
将匹配两条路线。因此,要解决此类问题,我们可以使用 Switch
。它只呈现一条路线,并且首先匹配任何路线。因此,这里定义路线的顺序很重要。
React-router-dom 下面使用的是 5.2.0 版本。以下说明不适用于 react-router-verion 6。有关重大更改,请参阅下面随附的 Academind 视频
你说得对!如果我们想在找不到匹配项时渲染特定组件,我们可以使用 switch,但让我解释一下原因。
让我们考虑一个例子来理解exact
和Switch
的作用
function App() {
return <Router>
<Route path="/">
<Home /> {/* This displays Home Page */}
</Route>
<Route path="/about">
<About /> {/* This displays About Page */}
</Route>
</Router>
}
路径 /about
与主页 (/
) 和关于页面 (/about
) 匹配,因为 /about
等于 /
home
+ about
。
换句话说,/about
有 /
和 about
(家和周围),所以它呈现两者。
为了避免渲染两个组件,我们在 第一个 出现的组件(在本例中为 /
)上使用 exact
,以便匹配该公共组件组件就停在那里(home /
是本例中的公共组件,因为它同时出现在 /
和 /about
中)。
意义,
/
/about
这两条路线的共同点是/
。要在 about
页面停止 /
的匹配,我们在 /
上放置一个名为 exact
prop 的限制,以便它在 /
停止匹配并且不会继续查看其他路线。
在具有 /
的更多路线中,将不会呈现主页,因为我们已经在 /
(主页)
上添加了 exact
限制
<Route exact path="/">
<Home /> {/* displays home. Stops matching / for further routes below because of exact prop */}
</Route>
要添加到此示例,现在让我们添加一个动态路由到 /about
{/* This displays About Page */}
<Route path="/about">
<About />
</Route>
{/* This displays About Sub Page */}
<Route path="/about/:id">
<AboutSubPage />
</Route>
此时,/about
和 /about/:id
(id 可以是 /about/ 之后的任何内容)将再次呈现到屏幕上,如下所示,因为 [=19= 上没有确切的属性].
让我们现在将 exact
属性添加到 /about
页面,以便 /about/2
只呈现关于子页面而不是关于页面
<Route exact path="/about">
<About />
</Route>
<Route path="/about/:id">
<AboutSubPage />
</Route>
现在仅显示 /about/2
的 AboutSubPage,如下所示
到目前为止一切顺利,但现在的主要问题是我们在哪里以及为什么需要 Switch
?
比方说,在我们当前的应用程序中,如果有人导航到一个不存在的页面。例如,/hello
不存在。然后我们得到一个空白屏幕,这不是一个好的用户体验。如果我们显示一条友好的消息说“抱歉,该页面不可用”,那就太好了。但是这里的 URL 匹配器应该是什么?我们可以说 *
(意思是任何文本)。
<Route path="*">
<h1>sorry the page is not available </h1>
</Route>
现在这会导致不需要的行为,其中 * 匹配每条路线(甚至是上面提到的路线)。在上述路由中添加的 exact prop 不会阻止这一点,因为通过添加 *,我们说“匹配每条路由并显示 h1”。
现在为了解决只有none以上匹配才考虑*路由(最后添加)的问题,我们使用Switch
.
通过使用 Switch 我们说 react-router,“如果其中一条路线匹配,请停止并且不要继续渲染下面的其他路线”。
这样,当它遇到/
或/about
时,它只是停止并且不渲染匹配*.
的最后一条路线
万一它没有找到任何路由,就像在 /hello
中一样,它会继续查找直到它匹配 *
,然后将我们的消息呈现到屏幕上。
完整代码
function App() {
return <Router>
<Switch> {* stops at first route it finds, so that error message at last is not displayed in each and every route *}
{/* This displays Home Page */}
<Route exact path="/">
<Home />
</Route>
{/* This displays About Page */}
<Route exact path="/about">
<About />
</Route>
{/* This displays About Page */}
<Route path="/about/:id">
<AboutSubPage />
</Route>
<Route path="*">
<h1>sorry the page is not available </h1>
</Route>
</Switch>
</Router>
}
更新
我们现在有 react-router version 6。有了这个,我们不再 Switch 和 exact
了解重大更改的资源 - https://www.youtube.com/watch?v=zEQiNFAwDGo&ab_channel=Academind
我已阅读有关 react-router Switch
的文档我理解Switch和Route的定义
但还是有些地方没看懂
如果我只想选择一个路由来渲染,我们可以像这样使用 Switch
<Switch>
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
</Switch>
我无法理解的一点是,我可以在没有开关的情况下获得相同的效果
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
那我们为什么要用Switch呢?什么时候需要用到Switch?
我发现了一个需要使用Switch的情况
如果我想在没有路径匹配时渲染特定组件
我们需要像这样在 Switch 中包装 Route
<Switch>
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route component={SpecificComponent} />
</Switch>
我说得对吗?
虽然在您的情况下您可以使用 exact 获得相同的效果,但情况可能并非总是如此。但是,如果您的其中一个路线包含嵌套路线,如果您在顶层有确切的路线,则无法使用嵌套路线。
Switch
在上述情况下达到了目的,因为它只呈现第一个匹配项
例如,
假设 Home 路线包含嵌套路线,例如
const Home = (props) => (
<div>
<Route path="/dashboard" component={Dashboard}/>
<Route path="/layout" component={Layout}/>
</div>
)
所以现在如果你写
<Route exact path="/" component={Home} />
当您访问 /dashboard
时。 Dashboard
组件无法呈现,因为没有路由与顶层的 /dashboard
匹配。
为了使示例 运行 正确,您可以使用 Switch
并重新排序路由,以便作为其他路径前缀的路径在末尾
<Switch>
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route path="/" component={Home} />
</Switch>
基本上,"exact" 关键字都有相同的用途。 (注意:使用检查当前 URL 是否以此路径开头的匹配算法。)但是当我们使用 时,路由声明或特异性的顺序很重要。需要在顶部添加更具体的 Route。你的情况
<Switch>
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route exact path="/" component={Home} />
</Switch>
在"exact"的情况下,当你传递"exact"时,只有路径完全匹配才会匹配这条路由。在您的情况下,主路径设置为准确。
<Route exact path="/" component={Home} />
<Route path="/a" component={A} />
<Route path="/b" component={B} />
让我列出Route
、exact
和Switch
的不同特征:
Route
进行部分匹配。 Route 的路径包含匹配(匹配很多)。exact
删除部分匹配。它可能匹配多个路由,以防我们在路由中使用通配符。Switch
只渲染第一个匹配的路由。Switch
路径完全匹配(只匹配一个)。
为了详细解释,我想说明路由匹配在有和没有 exact
的情况下是如何工作的。假设我们有以下代码并且我们没有使用 exact
.
因此,如果我们访问 /pagetwo
URL,Route
将进行部分匹配并呈现两条路线。让我们看看它是如何发生的。在下图中,我们正在查看地址栏和我们导航到的路径(提取的路径)以及正在匹配的路由。因此,Route
将在 extractedPath.contains(path-in-our-Route-declaration)
评估为真时呈现路线。
希望阐明 Route
在幕后是如何工作的。为了避免这种部分匹配,我们使用 exact
。使用 exact
解决问题,直到我们遇到一些特殊情况。假设我们有两条路线:
/users/create
/users/*
(路由中的通配符)。
在上述情况下,exact
将匹配两条路线。因此,要解决此类问题,我们可以使用 Switch
。它只呈现一条路线,并且首先匹配任何路线。因此,这里定义路线的顺序很重要。
React-router-dom 下面使用的是 5.2.0 版本。以下说明不适用于 react-router-verion 6。有关重大更改,请参阅下面随附的 Academind 视频
你说得对!如果我们想在找不到匹配项时渲染特定组件,我们可以使用 switch,但让我解释一下原因。
让我们考虑一个例子来理解exact
和Switch
function App() {
return <Router>
<Route path="/">
<Home /> {/* This displays Home Page */}
</Route>
<Route path="/about">
<About /> {/* This displays About Page */}
</Route>
</Router>
}
路径 /about
与主页 (/
) 和关于页面 (/about
) 匹配,因为 /about
等于 /
home
+ about
。
换句话说,/about
有 /
和 about
(家和周围),所以它呈现两者。
为了避免渲染两个组件,我们在 第一个 出现的组件(在本例中为 /
)上使用 exact
,以便匹配该公共组件组件就停在那里(home /
是本例中的公共组件,因为它同时出现在 /
和 /about
中)。
意义,
/
/about
这两条路线的共同点是/
。要在 about
页面停止 /
的匹配,我们在 /
上放置一个名为 exact
prop 的限制,以便它在 /
停止匹配并且不会继续查看其他路线。
在具有 /
的更多路线中,将不会呈现主页,因为我们已经在 /
(主页)
exact
限制
<Route exact path="/">
<Home /> {/* displays home. Stops matching / for further routes below because of exact prop */}
</Route>
要添加到此示例,现在让我们添加一个动态路由到 /about
{/* This displays About Page */}
<Route path="/about">
<About />
</Route>
{/* This displays About Sub Page */}
<Route path="/about/:id">
<AboutSubPage />
</Route>
此时,/about
和 /about/:id
(id 可以是 /about/ 之后的任何内容)将再次呈现到屏幕上,如下所示,因为 [=19= 上没有确切的属性].
让我们现在将 exact
属性添加到 /about
页面,以便 /about/2
只呈现关于子页面而不是关于页面
<Route exact path="/about">
<About />
</Route>
<Route path="/about/:id">
<AboutSubPage />
</Route>
现在仅显示 /about/2
的 AboutSubPage,如下所示
到目前为止一切顺利,但现在的主要问题是我们在哪里以及为什么需要 Switch
?
比方说,在我们当前的应用程序中,如果有人导航到一个不存在的页面。例如,/hello
不存在。然后我们得到一个空白屏幕,这不是一个好的用户体验。如果我们显示一条友好的消息说“抱歉,该页面不可用”,那就太好了。但是这里的 URL 匹配器应该是什么?我们可以说 *
(意思是任何文本)。
<Route path="*">
<h1>sorry the page is not available </h1>
</Route>
现在这会导致不需要的行为,其中 * 匹配每条路线(甚至是上面提到的路线)。在上述路由中添加的 exact prop 不会阻止这一点,因为通过添加 *,我们说“匹配每条路由并显示 h1”。
现在为了解决只有none以上匹配才考虑*路由(最后添加)的问题,我们使用Switch
.
通过使用 Switch 我们说 react-router,“如果其中一条路线匹配,请停止并且不要继续渲染下面的其他路线”。
这样,当它遇到/
或/about
时,它只是停止并且不渲染匹配*.
万一它没有找到任何路由,就像在 /hello
中一样,它会继续查找直到它匹配 *
,然后将我们的消息呈现到屏幕上。
完整代码
function App() {
return <Router>
<Switch> {* stops at first route it finds, so that error message at last is not displayed in each and every route *}
{/* This displays Home Page */}
<Route exact path="/">
<Home />
</Route>
{/* This displays About Page */}
<Route exact path="/about">
<About />
</Route>
{/* This displays About Page */}
<Route path="/about/:id">
<AboutSubPage />
</Route>
<Route path="*">
<h1>sorry the page is not available </h1>
</Route>
</Switch>
</Router>
}
更新 我们现在有 react-router version 6。有了这个,我们不再 Switch 和 exact
了解重大更改的资源 - https://www.youtube.com/watch?v=zEQiNFAwDGo&ab_channel=Academind