新版 React router 怎麼用? React-router-dom v6!

How to use Router with version 6+ ? React Router demo code / example code for React-router-dom .

Molly M
8 min readMar 9, 2022

✔ 前言

Router 改版後很多功能不支援,clone 舊專案 就會噴一堆 error RRRRR,本篇簡單整理異動的部份,方便大家快速 debug!

不過如果是維護舊專案會建議先不要升級 router 版本,因為有些相依套件還是只支援 v5 的,隨便升級可能會造成專案崩塌…(?。

✔目錄

▶ Switch ➪ Routes
▶ components ➪ element
▶ useHistory ➪ useNavigate
▶ 兩層 Router
▶ useLocation
▶ useParams
▶ useSearchParams
▶ No Match
▶ useRoutes
▶ 完整的 code

✔ 如何使用(2022.11.25補充) — 最 Basic 的版本

  • 安裝套件
npm i react-router-dom
  • index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import { BrowserRouter } from 'react-router-dom'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
)
  • app.js
function App() {
return (
<div className='App'>
<h1>Hello</h1>
<Routes>
<Route path='/' element={<Layout />}>
<Route index element={<Home />} />
<Route path='about' element={<About />} />
<Route path='dashboard' element={<Dashboard />} />
<Route path='*' element={<NoMatch />} />
</Route>
</Routes>
</div>
)
}

(element自行更換成元件名稱即可!)

✔ 異動

常用到但已經不支援的功能有:

  • Switch 改為使用 Routes,error 如下
export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'

新版寫法(外層必須加上 Routes )

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'<Router>
<Routes>
<Route element={<Home />} path={'/'}></Route>
<Route element={List} path='/list'></Route>
</Routes>
</Router>
  • components 改用 element,warning 如下
Matched leaf route at location "/" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.

新版寫法

<Route element={<Home />} path={'/'}></Route>
  • useHistory 改成 useNavigate,error 如下
error:Attempted import error: 'useHistory' is not exported from 'react-router-dom'

新版寫法

import { useNavigate } from "react-router-dom";const ABOUT = () => {
const navigate = useNavigate()
const onClick = () => {
navigate('/')
}
return (
<div>
<button onClick={onClick}>BACK</button>
</div>
)
}

✔ 進階運用

  • 兩層 Router 怎麼寫(Routes 中)

需要使用到 v6 新增的函式 Outlet,他會去渲染子層的元件,如果直接使用,渲染過程會出問題(雖然沒有 error )

直接看 code

其中的 List 元件,如果直接用 Link

const List = () => {
return (
<div>
list 頁面
<Link to={'/list/child1'}> one </Link>
<Link to={'/list/child2'}> two </Link>
</div>
)
}

雖然網址有變,但渲染是失敗的!

  • useLocation 抓取網址中的資訊
const location = useLocation()
console.log(location)

Hash #

  • useParams 抓取動態參數 (ex:http://localhost:3000/list/child2/666)
const params = useParams()
console.log(params, 'params')
  • useSearchParams 取得網址參數
const [getParams, setParam] = useSearchParams()
const name = getParams.getAll('name')

(getParams 取得參數 / setParam 設置參數)

  • No Match!如果網址沒有 match 的話
<Route
path='*'
element={
<main style={{ padding: '1rem' }}>
<p>There's nothing here!</p>
</main>
}
/>
  • useRoutes 更靈活的配置 router (路由)

寫在 App 元件底下的所有 router 可以包成一個值

const routeConfig = [
{
path: '/',
element: <Home />,
},
{ path: '/about', element: <About /> },
{
path: '/list',
element: <List />,
children: [
{ path: '/list/child1', element: <Child1 /> },
{ path: '/list/child2/:id', element: <Child2 /> },
],
},
]

使用方式

const element = useRoutes(routeConfig)
return (
<div>{element}</div>
)

完整的 code

✔ 總結

完成 (๑´ㅁ`)

--

--

Molly M

Molly — Software Developer / 職稱是軟體研發工程師。 什麼都寫,專精於前端及APP (ง•̀_•́)ง ! ❤ 合作發案討論疑難雜症請洽: momolly1024@gmail.com