原始碼:
example.js
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
export default function NestingExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
function Topics() {
let { path, url } = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${url}/rendering`}>Rendering with React</Link>
</li>
<li>
<Link to={`${url}/components`}>Components</Link>
</li>
<li>
<Link to={`${url}/props-v-state`}>Props v. State</Link>
</li>
</ul>
<Switch>
<Route exact path={path}>
<h3>Please select a topic.</h3>
</Route>
<Route path={`${path}/:topicId`}>
<Topic />
</Route>
</Switch>
</div>
);
}
function Topic() {
let { topicId } = useParams();
return (
<div>
<h3>{topicId}</h3>
</div>
);
}
效果圖:
————————————————————分割線———————————————————
相關知識:
巢狀路由:實現巢狀路由需要在一個<Route></Route>包裹的子元件中再使用<Route></Route>進行包裹內容即可。例如上面的 <Topics />元件。
useRouteMatch( ): 不帶引數的時候,返回當前元件路由匹配到的路徑內容。
如果帶引數,則相當於<Route></Route>的功能,可以進行路由匹配的判斷,並且不需要渲染<Route>元件。
解析:
頁面由兩個部分組成,ul包裹的兩個link標籤Home和Topics以及<Switch>包裹的路由元件,其中只有一個路由會被匹配並渲染。
前兩個圖,是頁面的主要兩個元件,<Home />和 <Topics />根據路由為/ 或者 /topics進行對應的渲染。
對於<Topics />元件,裡面又包括兩個部分,<h2>Topics</h2>,ul包裹的三個link和
<Switch>包裹的路由元件。這裡面的路徑必須和之前的路徑進行拼接,
例如
<Link to={`${url}/rendering`}>Rendering with React</Link>
<Route path={`${path}/:topicId`}>
這樣才可以對之前對內容進行保留。例如:
路徑為:/topics/components 則會分別匹配到<Route path="/topics"> 渲染出<Topics />並且匹配到<Route path={${path}/:topicId
}>渲染出<Topic />。