下面使用的 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(home 和 about),所以它会同时渲染两者。
为了避免在第一个出现的组件(本例中为/)上渲染我们使用exact的两个组件,以便该公共组件的匹配在此停止(主页/在这种情况下是通用组件,因为它同时存在于 / 和 /about)。
意义,
/
/about
这两条路线的共同点是/。为了在about 页面停止/ 的匹配,我们在/ 上设置了一个称为exact 属性的限制,以便它在/ 停止匹配并且不会继续检查其他路由。
在具有/ 的其他路由中,将不会渲染主页,因为我们已经在/ (home) 上添加了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/ 之后的任何内容)都将再次呈现到屏幕上,如下所示,因为 /about 上没有确切的属性。
现在让我们将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>
现在这会导致一个不受欢迎的行为,其中 this * 匹配每条路由(甚至是上面提到的路由)。在上述路由中添加的确切属性不会阻止这一点,因为通过添加 *,我们说的是“匹配每条路由并显示 h1”。
现在,为了解决只有在以上都不匹配时才应考虑 * 路由(最后添加)的问题,我们使用 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 版本 6。有了这个,我们不再有Switch和exact了
了解重大变化的资源 - https://www.youtube.com/watch?v=zEQiNFAwDGo&ab_channel=Academind