目前是基于 React Router 5.3.0
安装路由
- 安装:
npm install react-router-dom --save-dev
- 安装 TypeScript 的声明文件:
npm install @types/react-router-dom --save-dev
注意,这里安装的是react-router-dom
,而非react-router
:
- 当安装
react-router-dom
时,会自动安装react-router
核心框架。 -
react-router-dom
比react-router
多出了<Link>
<BrowserRouter>
这样的DOM 类组件。 -
react-router-dom
依赖react-router
,所以我们使用npm安装依赖的时候,不用再显式安装react-router
。
DOM 类组件:
-
<Link>
组件可以渲染出<a/>
标签 -
<BrowserRouter>
组件利用H5 API
实现路由切换 -
<HashRouter>
组件利用原生JS中的window.location.hash
实现路由切换
使用路由
-
BrowserRouter
:路由导航与原生浏览器操作行为一致 -
Route
:路由的路径解析原理与原生浏览器一致,可以自动识别url路径 -
Switch
:路径的切换以页面为单位,页面不会堆叠(一次只会渲染一个页面)
React路由常见搭配:<BrowserRouter/>
+ <Switch/>
+ <Route/>
最简单的路由例子:
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import { Home } from './pages'
function App() {
return (
<div>
<BrowserRouter>
{/* Switch 解决页面叠加问题,每次只渲染一个路由页面 */}
<Switch>
<Route path="/" component={Home} exact />
<Route path="/signIn" render={(() => <h1>登录页面</h1>)} />
<Route render={(() => <h1>404 页面</h1>)} />
</Switch>
</BrowserRouter>
</div >
);
}
export default App;
-
exact
属性可以使组件路由精准匹配 - 404页面的组件
Route
必须放在最后(所有页面都无法匹配的时候才生效)
路由传参
路由传参有两种方式:
- 使用
?
来引导参数,例:http://localhost:3000/?detail=11121314
(最常见的方式,使用问号?
) - 使用分段路由Segments,例:
http://localhost:3000/detail/11121314
( RESTful 的思维方式,参数作为URL的一部分,使用斜杠/
)
.
1. App.tsx
中跳转到详情页的路由(路由传参方法一)
<Route path="/detail/:id" component={Detail} />
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import { Home, Detail } from './pages'
function App() {
return (
<div className={styles.App}>
<BrowserRouter>
<Switch>
<Route path="/" component={Home} exact />
<Route path="/detail/:id" component={Detail} /> {/* 添加带有参数id的路由 */}
</Switch>
</BrowserRouter>
</div >
);
}
export default App;
2. Home.tsx
中跳转到详情页的路由(路由传参方法二)
- 使用高阶函数:
history.push('detail/123456')
import React from "react";
import { withRouter } from "react-router-dom"; // 高阶函数
const HomeComponent: React.FC = ({ history, location, match }) => {
console.log(history, location, match);
return (
<div onClick={() => history.push('detail/123456')}>跳转至详情页,并传递参数id</div>
);
}
export const Home = withRouter(HomeComponent); // 使用高阶函数封装路由
- 使用hook:
history.push('detail/123456')
import React from 'react';
import { useHistory, useLocation, useParams, useRouteMatch } from 'react-router-dom'; // hook
export const Home: React.FC = () => {
// 使用hook
const history = useHistory();
const location = useLocation();
const params = useParams();
const match = useRouteMatch();
return (
<div onClick={() => history.push('detail/123456')}>跳转至详情页,并传递参数id</div>
);
};
- 使用Link:
<Link to={'detail/123456'}>跳转</Link>
import React from "react";
import { Link } from "react-router-dom"; // link
export const Home: React.FC = () => {
return (
<Link to={'detail/123456'}>跳转至详情页,并传递参数id</Link>
);
}
3. Detail.tsx
详情页中获取参数
import React from 'react';
export const Detail: React.FC = (props) => {
console.log(props.match.params.id); // 获取路由传递过来的参数
}