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