如何添加 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 页面以响应嵌套路由?的主要内容,如果未能解决你的问题,请参考以下文章

如何让反应路由器响应 404 状态码?

Github 页面,图像无法加载 - 服务器以 404 响应图像检索

CodeIgniter 路由和 404 自定义错误

Laravel Ajax 路由问题(404 响应)

Rails-如何获得我的远程表单以JS响应?

Owin 身份令牌认证令牌端点以 404 响应