由於之前的專案一直使用的是V5版本,最新新建專案的時候,預設使用的是V6版本,根據官方的介紹,V6版本的新特性如下。
新特性
<Switch>
重新命名為<Routes>
;<Route>
的新特性變更;- 巢狀路由變得更簡單;
- 新鉤子useRoutes代替react-router-config;
- 用useNavigate代替useHistory;
- Link不再支援component 屬性;
- NavLink的exact屬性替換為end
- 大小減少:從20kb到8kb
<Switch>
重新命名為<Routes>
在V6版本中,<Switch>
元件被替換成<Routes>
元件,同時,component屬性被element屬性替換。
/* v5 */
<Switch>
<Route exact path="/" component={Home} />
<Route path="/user/:id" render={(routeProps) => <User id={routeProps.match.params.id} />} />
</Switch>
/* V6 */
<Routes>
<Route path="/" element={<Home />} />
<Route path="user/:id" element={<User id={id} />} />
</Routes>
同時,<Route>元件還修改了如下一些內容:
- 廢棄exact
- component/render被element替代
- routeProps可以在element中直接獲取
- 簡化的路徑匹配,僅支援動態:id樣式引數和*萬用字元,不再支援RegExp
支援巢狀路由
在V6版本中, <Route>
標籤支援巢狀,可以在一個檔案內配置巢狀路由,便於統一管理路由。
import { HashRouter as Router, Routes, Route } from 'react-router-dom'
import Home from '@/pages/demo/Home'
import Foo from '@/pages/demo/Foo'
import Bar from '@/pages/demo/Bar'
import BarDetail from '@/pages/demo/BarDetail'
import '@/assets/style/App.css'
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="foo" element={<Foo />} />
{/* 巢狀路由場景:需要在Bar(父路由的元件)宣告Outlet元件,用於渲染子路由 */}
<Route path="bar" element={<Bar />}>
<Route path=":id" element={<BarDetail />} />
</Route>
</Routes>
</Router>
)
}
export default App
Outlet
在巢狀路由場景,我們需要在父路由中使用Outlet元件,用於渲染子路由。
import { Outlet } from 'react-router-dom'
function Bar() {
return (
<div>
<div>Bar</div>
{/* 有巢狀路由的場景需要使用 */}
<Outlet />
</div>
)
}
export default Bar
巢狀路由可配置化
在V6版本中,我們可以使用useRoutes代替react-router-config配置。如果需要用到巢狀路由,那麼Outlet元件也是必要的。
import { useRoutes } from 'react-router-dom'
import Home from '@/pages/demo/Home'
import Foo from '@/pages/demo/Foo'
import Bar from '@/pages/demo/Bar'
import BarDetail from '@/pages/demo/BarDetail'
import '@/assets/style/App.css'
function App() {
let element = useRoutes([
{
path: '/',
element: <Home />
},
{
path: 'foo',
element: <Foo />
},
{
path: 'bar',
element: <Bar />,
children: [
{
path: ':id',
element: <BarDetail />
}
]
}
])
return element
}
export default App
需要注意的是,如果是使用此方式註冊路由配置,需要在入口檔案新增Router包裹App元件,否則會報錯。
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter as Router } from 'react-router-dom'
import App from '@/App'
import '@/assets/style/index.css'
ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
)
useNavigate代替useHistory
/* v5 */
const history = useHistory()
history.push('/home')
history.replace('/home')
history.goBack()
history.goForward()
history.go(2)
/* V6 */
const navigate = useNavigate()
navigate('/home')
navigate('/home', {replace: true})
navigate(-1)
navigate(1)
navigate(2)