前言
react-router-dom 是react中通用的路由組件,隨着新版本的更新,尤其是為了配合 react hook 的 v6版本,已經在使用上有了較大的變化,本文旨在對比舊版本(v5),以及介紹新版本的使用
react-router-dom 的版本介紹
v5文檔: https://v5.reactrouter.com/web/guides/quick-start
本文使用的兩個版本: v5(5.3.0) 和 v6(6.1.1)
其中:
v5版本既兼容了 class component(react v16.8前),又兼容了function component(v16.8及以后,即hook)
v6版本,若仍然使用this.props.history.push()
,此時props會提示是空值,v6文檔里把路由組件默認接受的三個屬性給移除了,官網文檔里給出的解決方案是使用useNavigate()這個hook,但是hook只能存在於無狀態組件(function component),無法用在類組件中(class component)
所以,仍然使用class commponent(類組件)進行項目開發的,建議react-router-dom 使用v5及以前的版本(最新的v5版本是 v5.3.0)
如果使用 function component(函數組件)進行項目開發的,建議使用最新的v6版本(v5版本雖然兼容了hook用法,但是相比v6還是有點區別)
react-router-dom 在 class component 類組件中的用法(v5.3.0)
import React from "react";
import { Router, Route, Switch, Redirect, HashRouter } from "react-router-dom";
import { createHashHistory } from "history";
...
const route = () => (
<HashRouter>
<Switch>
{/* 不可放在首行 */}
{/* <Redirect path="*" to="/" /> */}
<Route exact path="/" component={Home} />
<Route exact path="/listPage" component={ListPage} />
<Route exact path="/detailPage/:id" component={DetailPage} />
{/* 其他匹配重定向 */}
<Redirect path="*" to="/" />
</Switch>
</HashRouter>
);
export default route;
注意:<Router history={createHashHistory()}>
和 <HashRouter>
的區別 ==> 似乎沒有區別
路由跳轉:
this.props.history.push('/listPage')
: 路由入棧
this.props.history.replace('/listPage')
:路由替換
路由返回:
this.props.history.goBack();
: 返回上一級路由
攜帶參數:
state屬性攜帶參數: (隱式傳參)
this.props.history.push({
pathname: '/listPage',
state: {
aaa: 123
},
});
// 跳轉后新頁面 通過 this.props.history.location.state 獲取
// http://localhost:3000/#/listPage
search屬性攜帶參數:(顯式傳參)
this.props.history.push({
pathname: '/listPage',
search: '?bbb=456',
});
// 跳轉后新頁面 通過 this.props.history.location.search 獲取
// url: http://localhost:3000/#/listPage?bbb=456
路由傳參攜帶參數: (顯式傳參,需要router.js 中配合)
this.props.history.push({
pathname: '/detailPage' + '/' + id,
});
// 需要router.js 中路由配合: <Route exact path="/detailPage/:id" component={DetailPage} />
// 跳轉后新頁面 通過this.props.match.params.id 獲取
// url: http://localhost:3000/#/detailPage/789
react-router-dom 在 function component 函數組件中的用法(v6.1.1),即hook
import React from "react";
import { HashRouter, Route, Routes, Navigate } from "react-router-dom";
...
const route = () => (
<HashRouter>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/listPage" element={<ListPage />} />
<Route exact path="/detailPage/:id" element={<DetailPage />} />
<Route exact path="*" element={<Navigate to="/" />} />
{/* <Route exact path="*" element={<NotFound />} /> */}
</Routes>
</HashRouter>
);
export default route;
注意點:
- Routes 替換了 Switch
- Route中 element 替換了 component/render 屬性,且值是組件,而非組件名
- Navigate 組件替換了 Redirect
路由跳轉
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
// push
navigate(path);
// replace
navigate(path, {replace: true});
路由返回
const navigate = useNavigate();
// go back
navigate(-1);
攜帶參數:
state屬性攜帶參數: (隱式傳參)
const navigate = useNavigate();
navigate('/listPage', {
state: {
aaa: '123',
}
})
// url: http://localhost:3000/#/listPage
search屬性攜帶參數:(顯式傳參)
const navigate = useNavigate();
navigate('/listPage' + '?bbb=456')
// url: http://localhost:3000/#/listPage?bbb=456
路由傳參攜帶參數: (顯式傳參,需要router.js 中配合)
const navigate = useNavigate();
navigate('/detailPage' + '/' + id)
// 需要router.js 中路由配合: <Route exact path="/detailPage/:id" element={<DetailPage />} />
// 跳轉后新頁面 通過 const { id } = useParams(); 獲取,其中useParams 為 react-router-dom 內方法
// url: http://localhost:3000/#/detailPage/789
總結
v5 和 v6 的比較:
router.js 路由文件中:
- Switch 改用 Routes
- component/render 屬性 改為 element
<Route exact path="/listPage" element={<ListPage />} />
- Redirect 改用 Navigate
<Route exact path="*" element={<Navigate to="/" />} />
路由跳轉、傳參:
- history.push(path) 改為 navigate(path)
- history.replace(path) 改為 navigate(path, {replace: true})
- history.goBack() 改為 navigate(-1)
- v5 中的 hook 使用比較:
-v5: 使用 useHistory 的 history.push()
-v6: 使用 useNavigate 的 navigate()
參考
https://juejin.cn/post/7042849947451916296
https://juejin.cn/post/7040289734836355085
https://juejin.cn/post/6862305213148381198