我修改了文档中 React Router 嵌套路由中给出的示例,以在基本 url 中设置嵌套路由,如下所示。
我想要嵌套路由,如/Home1
和/Home2
直接在根 url 下。
export default function NestingExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
let { path, url } = useRouteMatch();
console.log({url, path});
return (
<div>
<h2>Homes</h2>
<ul>
<li>
<Link to="/home1">Home 1</Link>
{/* also tried <Link to={`${url}/home1`}>Home 1</Link> */}
</li>
<li>
<Link to="/home2">Home 2</Link>
</li>
</ul>
<Switch>
<Route exact path={path}>
<h3>Please select a home.</h3>
</Route>
<Route path={`${path}/home1`}>
<Home1 />
</Route>
<Route path={`${path}/home2`}>
<Home2 />
</Route>
</Switch>
</div>
);
}
function Home1() {
return (
<div>
<h3>Home1 Content</h3>
</div>
);
}
function Home2() {
return (
<div>
<h3>Home2 Content</h3>
</div>
);
}
浏览器中未显示错误,但不显示 Home1 页面。 是否可以直接在根目录下设置嵌套路由?
您需要对路由重新排序,以便基本路由是堆栈中的最后一个路由(使用 strict 关键字(
例如。
<Switch>
<Route strict path="/users" component={UsersRoutes} />
<Route strict path="/" compoent={PublicRoutes} />
</Switch>
有了这个,每个页面都可以呈现自己的Not Found
页面。
例如。
// within PublicRoutes
<Switch>
<Route exact path={path} component={() => <h1>Public Page</h1>} />
<Route path="*" component={() => <h1>Not found</h1>} />
</Switch>
https://codesandbox.io/s/react-router-nesting-025cn?file=/example.js
我没有尝试过这个,但我的猜测是在你的顶级路由器的路由中使用"exact"关键字,嵌套结构不再与 url 匹配。如果删除该属性,它是否有效?
详细信息: https://reacttraining.com/react-router/web/api/Route/exact-bool
我最终创建了一个单独的/home
路由,并将/
重定向到/home
以便能够在家中使用嵌套路由。
但我仍然对更聪明的答案感兴趣。
export default function NestingExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Redirect to="/home" />
</Route>
<Route path="/home">
<Home />
</Route>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
let { path, url } = useRouteMatch();
return (
<div>
<h2>Homes</h2>
<ul>
<li>
<Link to={`${url}/home1`}>Home 1</Link>
</li>
<li>
<Link to={`${url}/home2`}>Home 2</Link>
</li>
</ul>
<Switch>
<Route exact path={path}>
<h3>Please select a home.</h3>
</Route>
<Route path={`${path}/home1`}>
<Home1 />
</Route>
<Route path={`${path}/home2`}>
<Home2 />
</Route>
</Switch>
</div>
);
}
function Home1() {
return (
<div>
<h3>Home1 Content</h3>
</div>
);
}
function Home2() {
return (
<div>
<h3>Home2 Content</h3>
</div>
);
}
问题是 react-router 不会从path
和url
中去除尾部斜杠。
所以在根路径上:path === '/'
因此,当您连接它时:
<Route exact path={`${path}/home1`}>
你最终得到
<Route exact path="//home">
与任何路线都不匹配
解决此问题的最简单方法是通过删除尾部斜杠来规范化路径和 url 变量
let { path, url } = useRouteMatch();
//strip trailing slashes
path = path.replace(//$/, '');
url = url.replace(//$/, '');
您的完整示例是
export default function NestingExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
<Switch>
<Route path="/">
<Home />
</Route>
{/** Note That both "/" and "/home" will work */}
<Route path="/home">
<Home />
</Route>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
let { path, url } = useRouteMatch();
//strip trailing slashes
path = path.replace(//$/, '');
url = url.replace(//$/, '');
return (
<div>
<h2>Homes</h2>
<ul>
<li>
<Link to={`${url}/home1`}>Home 1</Link>
</li>
<li>
<Link to={`${url}/home2`}>Home 2</Link>
</li>
</ul>
<Switch>
<Route exact path={${path}/}>
<h3>Please select a home.</h3>
</Route>
<Route exact path={`${path}/home1`}>
<Home1 />
</Route>
<Route exact path={`${path}/home2`}>
<Home2 />
</Route>
</Switch>
</div>
);
}
function Home1() {
return (
<div>
<h3>Home1 Content</h3>
</div>
);
}
function Home2() {
return (
<div>
<h3>Home2 Content</h3>
</div>
);
}