如何添加 404 页面以响应嵌套路由?
Posted
技术标签:
【中文标题】如何添加 404 页面以响应嵌套路由?【英文标题】:How to add a 404 page in react with nested routing? 【发布时间】:2021-04-07 03:39:40 【问题描述】:我已经构建这个应用程序有一段时间了,我想可能是时候在我的index.js
中添加一个 404 页面了(我可能应该先这样做,真让我感到羞耻)。问题是,当路由不匹配时,我似乎无法渲染 404 页面,而只是显示一个空白页面。我在网上查看过,但没有多少示例使用带有嵌套路由的 404 页面,就像我在 index.js
文件中看到的那样:
ReactDOM.render((
<BrowserRouter>
<Switch>
<Route path='/customer'>
<CustomerPortal>
<Route exact path='/customer' component=CustomerPortalHome />
<Route path='/customer/quote/:info?' component=CustomerQuote />
<Route path='/customer/direct_quote/:ref?' component=Referral />
<Route path='/customer/ad/:info?' component=Ad />
</CustomerPortal>
</Route>
<Route path='/pay'>
<CustomerPortal>
<Route exact path='/pay' component=PaymentPortal />
<Route path='/pay/:txn' component=PaymentPage />
</CustomerPortal>
</Route>
<Route exact path="/login" component=Login />
<Route path='/'>
<Auth>
<App>
<Route exact path='/' component=Dashboard />
<Route path='/stores' component=Stores />
<Route path='/archives' component=Archives />
<Route path='/users' component=Users />
<Route path='/contracts' component=Contracts />
<Route path='/graphics' component=Graphics />
<Route exact path='/submit_contract' component=MyContracts />
<Route path='/submit_contract/new' component=ContractForm />
<Route path='/submit_contract/renewal/:id' component=ContractForm />
</App>
</Auth>
</Route>
<Route component=NotFound />
</Switch>
</BrowserRouter>), document.getElementById('appRoot'));
我的应用程序有一个客户端和一个管理端,因此有多个不同的路由。我尝试在许多不同的地方移动我的NotFound
组件,但我仍然没有得到我想要的结果。保持它现在的位置,如果我试图去/someroute
的路线,它只会显示一个空白页。如果我将我的NotFound
组件移动到底部的App
组件内,这将在我的所有其他页面上显示 404,这也不是我想要发生的。嵌套路由的问题在于,即使我要去任何与主路由 /
匹配的地方,它也会显示在那里,所以我认为在切换结束时使用它是没有意义的,但也许我错了。如果有人对我如何使这项工作适用于所有路线有任何想法或建议,那就太好了。蒂亚!
编辑
通过一些蛮力试验和错误以及更多研究,我能够自己解决这个问题。我可以通过将嵌套的Switch
组件添加到我的每条主要路线中来解决这个问题,然后将我的NotFound
组件放在每条主要路线的底部,就像这样。
ReactDOM.render((
<BrowserRouter>
<Switch>
<Route path='/customer'>
<CustomerPortal>
<Switch>
<Route exact path='/customer' component=CustomerPortalHome />
<Route path='/customer/quote/:info?' component=CustomerQuote />
<Route path='/customer/direct_quote/:ref?' component=Referral />
<Route path='/customer/ad/:info?' component=Ad />
<Route component=NotFound />
</Switch>
</CustomerPortal>
</Route>
<Route path='/pay'>
<CustomerPortal>
<Switch>
<Route exact path='/pay' component=PaymentPortal />
<Route path='/pay/:txn' component=PaymentPage />
<Route component=NotFound />
</Switch>
</CustomerPortal>
</Route>
<Route exact path="/login" component=Login />
<Route path='/'>
<Auth>
<App>
<Switch>
<Route exact path='/' component=Dashboard />
<Route exact path='/stores' component=Stores />
<Route exact path='/archives' component=Archives />
<Route exact path='/users' component=Users />
<Route exact path='/contracts' component=Contracts />
<Route exact path='/graphics' component=Graphics />
<Route exact path='/submit_contract' component=MyContracts />
<Route path='/submit_contract/new' component=ContractForm />
<Route path='/submit_contract/renewal/:id' component=ContractForm />
<Route component=NotFound />
</Switch>
</App>
</Auth>
</Route>
<Route component=NotFound />
</Switch>
</BrowserRouter>), document.getElementById('appRoot'));
我还为所有非动态路径添加了精确路径。希望这对某人有所帮助。
【问题讨论】:
这似乎是最适合 .htaccess 文件的任务。 @jcklopp 我不知道那是什么,所以我想我会看看,谢谢。 它非常简单。在您的 Web 根目录中创建一个名为 .htaccess 的文件,其中包含有关如何处理 http 404 错误的指令。如果您需要一个起点,可以试试这个链接:***.com/questions/19962787/… 【参考方案1】:问题是它进入了内部
<Route path='/'>
因为exact
关键字不存在,因此它匹配'/something' 和'/'。
如果我尝试猜测您的 Auth
组件,那么我这边给您的第一个简单解决方案将如下所示
<Route path='/'>
<Auth>
<App>
...
</App>
<Route component=NotFound />
</Auth>
<Route component=NotFound />
</Route>
<Route component=NotFound />
```
【讨论】:
我的意思是它会像添加所有父路由的确切路径一样简单吗? 对不起,我没听懂你问了什么【参考方案2】:根据我在您的代码中观察到的情况。 您需要在嵌套路由器中添加带有 NotFound 组件的路由器作为子路由器,因为您的父路由器不包含确切的属性。
【讨论】:
【参考方案3】:您可以使用现有的,但将路径更改为 path="*"。这将使任何不是已定义路径的内容都转到 404 页面。
<Route path="*" component=PageNotFound />
这里有教程:https://naveenda.medium.com/creating-a-custom-404-notfound-page-with-react-routers-56af9ad67807
【讨论】:
这给了我同样的问题,页面显示为空白并且不呈现NotFound
组件。以上是关于如何添加 404 页面以响应嵌套路由?的主要内容,如果未能解决你的问题,请参考以下文章