1、<Switch>
标签更换成 <Routes>
标签
含义:是唯一的因为它仅仅只会渲染一个路径。相比之下(不使用<Switch>
包裹的情况下),每一个被location匹配到的将都会被渲染
2、 <Route>
的新特性变更
component/render
被element
替代
import Profile from './Profile';
// v5
<Route path=":userId" component={Profile} />
<Route
path=":userId"
render={routeProps => (
<Profile routeProps={routeProps} animate={true} />
)}
/>
// v6
<Route path=":userId" element={<Profile />} />
<Route path=":userId" element={<Profile animate={true} />} />
3、<Redirect>
标签删除
解决方案:新版的路由需要引入<Navigate>
标签
import { HashRouter as Router, Route, Routes, Navigate } from 'react-router-dom'
<Router>
<Routes>
<Route path='/login' element={<Login/>}/>
<Route path='/admin' element={<Admin/>}/>
<Route path="*" element={<Navigate to="/login" />} />
</Routes>
</Router>
4、 嵌套路由变得更简单
<Route children>
已更改为接受子路由- 比
<Route exact>
和<Route strict>
更简单的匹配规则。 <Route path>
路径层次更清晰。
1)简化嵌套路由定义
v5
中的嵌套路由必须非常明确定义,且要求在这些组件中包含许多字符串匹配逻辑
// v5
import { BrowserRouter, Switch, Route, Link, useRouteMatch } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Switch>
<Route path="/profile" component={Profile} />
</Switch>
</BrowserRouter>
);
}
function Profile() {
let { path, url } = useRouteMatch();
return (
<div>
<Link to={`${url}/me`}>My Profile</Link>
<Switch>
<Route path={`${path}/me`}>
<Me />
</Route>
<Route path={`${path}/:id`}>
<Index />
</Route>
</Switch>
</div>
);
}
而在v6
中,不需要任何useRouteMatch()
// v6
import { BrowserRouter, Routes, Route, Link, } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="profile/*" element={<Profile/>} />
</Routes>
</BrowserRouter>
);
}
function Profile() {
return (
<div>
<Link to="me">My Profile</Link>
<Routes>
<Route path="me" element={<Me />} />
<Route path=":id" element={<Index />} />
</Routes>
</div>
);
}
2) 新API
:Outlet
import { BrowserRouter, Routes, Route, Link, } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="profile" element={<Profile />}>
<Route path=":id" element={<MyProfile />} />
<Route path="me" element={<OthersProfile />} />
</Route>
</Routes>
</BrowserRouter>
);
}
function Profile() {
return (
<div>
<nav>
<Link to="me">My Profile</Link>
</nav>
{/*
将直接根据上面定义的不同路由参数,渲染<MyProfile />或<OthersProfile />
*/}
<Outlet />
</div>
)
}
3) 多个<Routes />
以前,我们只能 在React App
中使用一个 Routes
。但是现在我们可以在React App
中使用多个路由,这将帮助我们基于不同的路由管理多个应用程序逻辑
import React from 'react';
import { Routes, Route } from 'react-router-dom';
function Dashboard() {
return (
<div>
<p>Look, more routes!</p>
<Routes>
<Route path="/" element={<DashboardGraphs />} />
<Route path="invoices" element={<InvoiceList />} />
</Routes>
</div>
);
}
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="dashboard/*" element={<Dashboard />} />
</Routes>
);
}
5、 用useNavigate
代替useHistory
// v5
import { useHistory } from 'react-router-dom';
function MyButton() {
let history = useHistory();
function handleClick() {
history.push('/home');
};
return <button onClick={handleClick}>Submit</button>;
};
现在,history.push()
将替换为navigate()
// v6
import { useNavigate } from 'react-router-dom';
function MyButton() {
let navigate = useNavigate();
function handleClick() {
navigate('/home');
};
return <button onClick={handleClick}>Submit</button>;
};
history
的用法也将被替换成:
// v5
history.push('/home');
history.replace('/home');
// v6
navigate('/home');
navigate('/home', {replace: true});
6、新钩子useRoutes
代替react-router-config
const App() => {
const element = useRoutes([
{ path: 'login', element: <Login /> },
{ path: 'invoices',
element: <Invoices />,
children: [
// useRoutes 可以使用index:true 来打开路由默认页面
{ index: true, element: <Yeng /> },
{ path: ':id', element: <Invoice /> },
{ path: 'sent', element: <SentInvoices /> }
]
},
// 重定向 需要借助 `<Navigate>` 标签
{ path:'/', element: <Navigate to="/login" /> },
// 404找不到
{ path: '*', element: <NotFound /> }
]);
return element;
}
// useRoutes 第二个参数 字符串路由或者路由对象 路由对象必须包含pathname参数
useRoutes([], '/index')
相当与
useRoutes([{
{ path: '/index', element: <IndexBox />,},
{ index: true, element: <IndexBox /> }
}])
7、注意点
- React Router v6使用简化的路径格,仅支持2种占位符:动态:
id
样式参数和*
通配符 - 以下都是v6中的有效路由路径:
/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
/files-*
- 使用
RegExp
正则匹配的路径将无效:
/users/:id?
/tweets/:id(\d+)
/files/*/cat.jpg
-
v6
中的所有路径匹配都将忽略URL上的尾部"/
"。实际上,<Route strict>
已被删除并且在v6中无效。这并不意味着您不需要使用斜杠。 -
在
v5
版本之前的路径,存在路由歧义- 当前路径:"
/users
",则<Link to="me">
将跳转<a href="/me">
。 - 当前路径:"
/users/
",则<Link to="me">
将跳转<a href="/users/me">
。
- 当前路径:"
-
React Router v6
修复了这种歧义,取消了尾部"/
":- 当前路径:"
/users
",则<Link to="me">
将跳转<a href="/users/me">
。 - 当前路径:"
/users
",则<Link to="../me">
将跳转<a href="/me">
。
- 当前路径:"