使用Reach Router导航到404路线



我有以下路由配置:

<Router>
<NotFound default />
<ResourcesContainer path="/resources" />
<ResourceContainer path="/resources/:id" />
...
</Router>

这会捕获任何未处理的路由,并在未找到的URL处呈现<NotFound />组件,因此如果我键入example.com/blah,我会看到呈现的<NotFound />组件,在地址栏中我会看到example.com/blah。我还在页面上使用这个URL来显示一条消息:

找不到页面"example/blah"。

到目前为止还不错。然而,我还需要在/resources/*路由中处理来自内部的404。我的<ResourcesContainer/>组件使用路径的最后一部分来访问带有该id的资源的GraphQL API。如果API返回来告诉客户端资源不存在,我想模仿上面概述的行为。但是,我没有可导航的页面。我可以复制<NotFound />路由,并给它一个/404的显式path,然后导航到它。然而,URL将是/404,而不是未找到的原始resources/*路径。

以下解决了部分问题,给了我一个重定向ot的页面,但意味着在所有情况下URL都被重写为/404

<Router>
<ResourcesContainer path="/resources" />
<ResourceContainer path="/resources/:id" />
<NotFound path="/404" />
<Redirect noThrow from="*" to="/404" />
...
</Router>

如何设置此设置,以便在不丢失原始URL的情况下将navigate路由到<NotFound />

如果找不到资源,最好的选择是将ResourceContainer的渲染方法更改为渲染NotFound

但是,如果您不想对ResourceContainer进行更改,您可以用这样的错误边界来包装它:

class NotFoundErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { notFound: false };
}
static getDerivedStateFromError(error) {
// Filter which kind of errors you want to show the error boundary for
return { notFound: true };
}
render() {
if (this.state.notFound) {
// You can render any custom fallback UI
return <NotFound />;
}
return this.props.children; 
}
}

并像一样使用它

<NotFoundErrorBoundary>
<ResourceContainer path="/resources/:id" />
</NotFoundErrorBoundary>

您的ResourceContainer可能会抛出NotFoundErrorBoundary可以识别的错误,这可能表示资源未找到,它应该呈现NotFound页面,而不是子页面。

需要明确的是,我并不鼓励您使用ErrorBoundary。在我看来,这会使事情过于复杂。我只是向你介绍信息,你如何使用它取决于你。此外,它可能在另一个上下文中对您有用,具体取决于用例。

错误边界不是一个很好的处理方法。官方网站鼓励我们使用嵌套路由哲学。例如,最佳做法是在每个孩子体内使用<Router>:根:

<Router>
<NotFound default />
<ResourcesContainer path="/resources/*" />
...
</Router>

ResourcesContainer.jsx:

<Router>
<NotFound default />
<ResourcesList path="/" />
<ResourceDetail path="/:id" />
...
</Router>

如果我们在API调用中得到404,如何渲染<NotFound />很容易:

if (API.error) return <NotFound />;
if (API.data) return ...;

如何简化它我们可以用这样的包装:未找到路由器WIth

<Router>
<NotFound default />
{children}
</Router>

在我看来,这不是路由问题。呈现/resources/:id的组件基本上有三种状态:loadingfoundData404。如果只为每个状态渲染不同的组件,则可以只渲染相同的404组件。很简单,如果你不想更改url,就不要导航。

相关内容

  • 没有找到相关文章

最新更新