foreword
Recently completed the development of the company's new project, the related technology stack has used the latest version, and react router also uses the v6 version, so take this opportunity to sort out the difference between react router v5 and v6, as well as some new features of v6. In the case of the original project still using the old version of react router, it is not recommended to upgrade directly, and there may be many changes.
This article will also be synchronized on my Github blog
v5 upgrade v6 guide
<Switch>
replace all <Routes>
v5
<BrowserRouter>
<Menu />
<Switch>
<Route component={Home} path="/home"></Route>
<Route component={List} path="/list"></Route>
<Route component={Detail} path="/detail"></Route>
<Route component={Category} path="/category"></Route>
</Switch>
</BrowserRouter>
// Category.tsx
<Switch>
<Route component={CategoryA} path="/category/a"></Route>
<Route component={CategoryB} path="/category/b"></Route>
</Switch>
Switch
Component role: render the first location matched and as a child element <Route>
or <Redirect>
, it will only render a path
v6
<BrowserRouter>
<Menu />
<Routes>
<Route element={<Home />} path="/home"></Route>
<Route element={<List />} path="/list"></Route>
<Route element={<Detail />} path="/detail"></Route>
<Route element={<Category />} path="/category">
{/* children 写法嵌套子路由,path是相对路径 */}
<Route element={<CategoryA />} path="a"></Route>
<Route element={<CategoryB />} path="b"></Route>
</Route>
</Routes>
</BrowserRouter>
The main advantages of Switch
compared to Routes
are:
- All
Routes
within<Route>
and<Link>
support relative routing (if it starts with/
is absolute). This makes the code in<Route path>
and<Link to>
leaner and more predictable - Routing is based on the best path match, rather than traversing the selected ones in order
- Routes can be nested in the same place without having to be scattered in different components
Notice:
-
Routes
cannot be considered as a replacement forSwitch
.Switch
feature is matching onlyRoute
component but itself is optional, you can useRoute
component instead ofSwitch
.Route
组件则v6 的Routes
是必选的,Routes
Route
component, otherwise an error will be reported.
Route component properties
Route
of render
or component
to element
// v5
<Route component={Home} path="/home"></Route>
// v6
<Route element={<Home />} path="/home"></Route>
Simplified path
format, only two dynamic placeholders are supported
-
:id
dynamic parameters -
*
wildcard, can only be used at the end ofpath
a277538e0e76222c753722cbba120413---, such asusers/*
The correct way to write v6 path
:
/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
v6 path
wrong spelling
/users/:id? // ? 不满足上面两种格式
/tweets/:id(\d+) // 有正则表达式,不满足
/files/*/cat.jpg
/files-*
Enable case sensitivity for route matching caseSensitive
caseSensitive
, for regular matching path
Whether to enable ignore mode, that is, whether to ignore case when matching
<Routes caseSensitive>
All path matches ignore trailing slashes on URLs
Add Outlet component
Role: usually used to render sub-routes, similar to the role of slots, used to match sub-routes element
export default function Category() {
return (
<div>
<div>
<Link to="a">跳转 CategoryA</Link>
</div>
<div>
<Link to="b">跳转 CategoryB</Link>
</div>
{/* 自动匹配子路由的渲染 */}
<Outlet />
</div>
)
}
Link component properties
Whether the to attribute has/is the difference with the current URL
In v5, there is uncertainty if to
does not start with /
, depending on the current URL.
比如当前URL 是/category
, <Link to="a">
会渲染成<a href="/a">
; 而当前URL /category/
,那么又会渲染成<a href="/category/a">
.
在v6 中,无论当前URL 是/category
/category/
, <Link to="a">
成<a href='/category/a'>
,即忽略URL 上的尾部斜杠Unified rule processing.
The to attribute supports relative positions and notation such as '..' and '.'
<ul>
<li>当前页面:CategoryA</li>
<li>当前url:/category/a</li>
<li>
{/* /list */}
<Link to="../../list">跳转到list页面</Link>
</li>
<li>
{/* /category/b */}
<Link to="../b">跳转到category/b页面</Link>
</li>
<li>
{/* /category/a */}
<Link to=".">跳转到当前路由</Link>
</li>
</ul>
Pass the state property directly
// v5:
<Link to={{ pathname: "/home", state: state }} />
// v6:
<Link to="/home" state={state} />
Added target attribute
type HTMLAttributeAnchorTarget = '_self' | '_blank' | '_parent' | '_top' | (string & {})
NavLink
-
<NavLink exact>
Attribute name changed to<NavLink end>
- Removed
activeStyle
,activeClassName
attributes
<NavLink
to="/messages"
- style={{ color: 'blue' }}
- activeStyle={{ color: 'green' }}
+ style={({ isActive }) => ({ color: isActive ? 'green' : 'blue' })}
>
Messages
</NavLink>
Remove Redirect
redirect component
The main reason for removal is bad for SEO
// v5
<Redirect from="/404" to="/home" />
// v6 使用 Navigate 组件替代
<Route path="/404" element={<Navigate to="/home" replace />} />
Added useNavigate
instead of useHistory
The function component can be obtained by useHistory history
object, which is used for page jump navigation
// v5
import { useHistory } from 'react-router-dom'
export default function Menu() {
const history = useHistory()
return (
<div>
<div
onClick={() => {
history.push('/list')
}}
>
编程式路由跳转list页面
</div>
</div>
)
}
// v6
import { useNavigate } from 'react-router-dom'
export default function Menu() {
const navigate = useNavigate()
return (
<div>
<div
onClick={() => {
navigate('/list') // 等价于 history.push
}}
>
编程式路由跳转list页面
</div>
</div>
)
}
Here are some other distinctions
//v5
history.replace('/list')
// v6
navigate('/list', { replace: true })
// v5
history.go(1)
history.go(-1)
// v6
navigate(1)
navigate(-1)
Added useRoutes
instead of react-router-config
useRoutes
Generate the corresponding routing rules according to the routing table
useRoutes
must be used in<Router>
- react-router-config : for centralized management of routing configuration
import { useRoutes } from 'react-router-dom'
import Home from './components/Home'
import List from './components/List'
function App() {
const element = useRoutes([
{ path: '/home', element: <Home /> },
{ path: '/list', element: <List /> },
])
return element
}
export default App
Added useSearchParams
v6 provides useSearchParams
returns an array to get and set url parameters
import { useSearchParams } from 'react-router-dom'
export default function Detail() {
const [searchParams, setSearchParams] = useSearchParams()
console.log('getParams', searchParams.get('name'))
return (
<div
onClick={() => {
setSearchParams({ name: 'jacky' })
}}
>
当前页面:Detail 点我设置url查询参数为name=jacky
</div>
)
}
Not supported <Prompt>
In the old version, the Prompt
component can implement page closing interception, but it is not supported in the v6 version yet. If you want to upgrade v6 from v5, you must consider it clearly.
// v5
<Prompt
when={formIsHalfFilledOut}
message="Are you sure you want to leave?"
/>
Summarize
Summary of the differences between v5 and v6 at the usage level:
-
<Switch>
replace all<Routes>
Route new feature changes
-
render
andcomponent
changed toelement
and support nested routing -
path
supports relative paths; simplifiedpath
format, only supports two dynamic placeholders - Route matching case sensitivity is enabled
caseSensitive
- All path matches ignore trailing slashes on URLs
/
-
- Added
Outlet
component is used to render matched sub-routes - Remove
Redirect
redirect component, because it is not good for SEO - Added
useNavigate
replaceduseHistory
- Added
useRoutes
instead ofreact-router-config
- Added
useSearchParams
to get and set url parameters
The Demo address of this article
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。