目前是基于 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); // 获取路由传递过来的参数
}
