react-router-dom 在hook中的使用 v6 和 v5的對比

前言

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;

注意點:

  1. Routes 替換了 Switch
  2. Route中 element 替換了 component/render 屬性,且值是組件,而非組件名
  3. 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 路由文件中:

  1. Switch 改用 Routes
  2. component/render 屬性 改爲 element
    <Route exact path="/listPage" element={<ListPage />} />
  3. Redirect 改用 Navigate
    <Route exact path="*" element={<Navigate to="/" />} />

路由跳轉、傳參:

  1. history.push(path) 改爲 navigate(path)
  2. history.replace(path) 改爲 navigate(path, {replace: true})
  3. history.goBack() 改爲 navigate(-1)
  4. v5 中的 hook 使用比較:
    -v5: 使用 useHistory 的 history.push()
    -v6: 使用 useNavigate 的 navigate()

 


參考

https://juejin.cn/post/7042849947451916296
https://juejin.cn/post/7040289734836355085
https://juejin.cn/post/6862305213148381198

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章