在尝试在react router dom v5中创建嵌套路由时,我发现this answer解释了如何做得很好
(请看一下这里的代码,因为它与上面提到的答案有些不同)
const NotFound = () => <h1>Not Found</h1>;
function Layouts() {
return (
<Switch>
<Route path="/auth" component={AuthLayout} />
<Route path="/app" component={AppLayout} />
<Route path="/" component={NotFound} />
</Switch>
);
}
const Signup = () => <p>Login</p>;
const Login = () => <p>Sign up</p>;
function AuthLayout() {
return (
<div>
<h1>Auth Layout</h1>
<Route path="/auth/signup" exact component={Signup} />
<Route path="/auth/login" exact component={Login} />
{/* Commenting this because I want to go to NotFound component */}
{/* <Redirect from="/auth" to="/auth/login" exact /> */}
</div>
);
}
const Home = () => <p>Home</p>;
const Dashboard = () => <p>Dashboard</p>;
function AppLayout() {
return (
<div>
<h1>App Layout</h1>
<Route path="/app/home" exact component={Home} />
<Route path="/app/dashboard" exact component={Dashboard} />
{/* Commenting this because I want to go to NotFound component */}
{/* Redirect from="/app" to="/app/home" exact /> */}
</div>
);
}
但这有一个问题,如果您使用/app/somethingnotfound
进入一条路线,而不会到达<Route path="/" component={NotFound} />
,则它将“停留在” AppLayout
中并且不呈现任何路线。
在这种情况下,如何使/app/somethingnotfound
转到<Route path="/" component={NotFound} />
?
请更加清楚:我不想只在<Route component={NotFound} />
和AuthLayout
内添加AppLayout
,因为它会渲染其他内容。我真正需要的是显示最高级别的NotFound
。
答案 0 :(得分:1)
找不到组件通常是这样的:
<Router>
<Switch>
<Route exact path="/auth" component={AuthLayout} />
<Route exact path="/app" component={AppLayout} />
<Route component={NotFound} />
</Switch>
</Router>
但是您无法将/auth
和/app
标记为exact
,因为它们包含嵌套路由。因此,您应该这样做:
<Router>
<Switch>
<Route path="/auth" component={AuthLayout} />
<Route path="/app" component={AppLayout} />
<Route exact path="/404" component={NotFound} />
<Redirect to='/404' />
</Switch>
</Router>
和具有嵌套路由的组件(例如AppLayout
)
<>
<h1>App Layout</h1>
<Switch>
<Route path="/app/home" exact component={Home} />
<Route path="/app/dashboard" exact component={Dashboard} />
<Redirect to="/404" />
</Switch>
</>
答案 1 :(得分:0)
在查看我发现的this solution的github问题时,您会创建一个“全局未找到的页面”,如果找不到路由,则通过该页面通过状态,然后仅渲染该路由而不是其他路由。
const NotFound = () => <div className="not_found"><h1>Not Found</h1></div>;
const RouteNotFound = () => <Redirect to={{ state: { notFoundError: true } }} />;
const CaptureRouteNotFound = withRouter(({children, location}) => {
return location && location.state && location.state.notFoundError ? <NotFound /> : children;
});
const Settings = () => {
return (
<Switch>
<Route path="/settings/account" render={() => <h1>Account Settings</h1>} />
<Route path="/settings/profile" render={() => <h1>Profile Settings</h1>} />
<RouteNotFound />
</Switch>
);
};
const AppShell = ({children}) => {
return (
<div className="application">
<header>Application</header>
{children}
</div>
);
};
const Application = () => {
return (
<Router>
<CaptureRouteNotFound>
<AppShell>
<Switch>
<Route path="/settings" render={() => <Settings />} />
<Route path="/profile" render={() => <h1>User Profile</h1>} />
<RouteNotFound />
</Switch>
</AppShell>
</CaptureRouteNotFound>
</Router>
);
};
答案 2 :(得分:0)
<Route path="/" component={NotFound} />
与所有未实现的嵌套都不匹配,因为Switch
组件中的Layouts
将仅呈现与Route
。在您的情况下,当您通过路径pathname
时,它将路由与AppLayout
组件匹配,这就是为什么它仅呈现/app/somethingdoesntexist
组件的原因。
解决方案
例如,最好使用嵌套的AppLayout
组件为每个布局实现NotFound
路由
Switch
在上述情况下,我们使用function AppLayout() {
const { path, url } = useRouteMatch();
return (
<Switch>
<Route path={`${path}/home`} exact component={Home} />
<Route path={`${path}/dashboard`} exact component={Dashboard} />
<Route path="*" component={NotFound} />
</Switch>
);
}
钩子获得了匹配的路径,并嵌套了另一个useRouteMatch
组件,该组件将呈现与Switch
匹配的任何嵌套路由,并提供后备{ {1}}将路径指定为path
,将在找不到匹配项时呈现Route
组件。
这是解决方案的完整示例 codesandbox。
您还可以看到文档中提供的嵌套example。