v6的改进:
参考代码结构:https://stackblitz.com/edit/github-agqlf5?file=src/App.jsx
官网:https://reactrouter.com
1.useHistory钩子废弃,改为useNavigate 钩子
import { useNavigate } from "react-router-dom";
export default function Invoice() {
let navigate = useNavigate();
return (
<button
onClick={() => {
navigate("/invoices");
}}
>
Delete
</button>
);
}
2.Switch组件更名为Routes组件,且子元素只允许是Route组件或React.Fragment组件
// v5
<Switch>
<Route path="/" element={<App />}>
</Switch>
// v6
<Routes>
<Route path="/" element={<App />}>
</Routes>
Uncaught Error: [YourCustomComp] is not a
component. All component children of must be a or
3.Route的component和render属性废弃,统一改用element属性,注意它接受一个jsx元素,而非组件。
例如:element = {
或hello
}element = {
。
<Route path="/" element={<App />} />
4.Route之间可以直接进行嵌套,形成树形结构
<Routes>
<Route path="/" element={<App />}>
<Route path="expenses" element={<Expenses />} />
<Route path="invoices" element={<Invoices />}>
<Route path=":invoiceId" element={<Invoice />} />
</Route>
</Route>
</Routes>
5.Route的strict属性废弃,不在需要考虑路径结尾是否有 /
。
6.Route添加了index属性,拥有index属性的Route,它的path属性(写了也无效,等于这俩属性互斥)无效,它和其他子路由平级,它在父级路由未匹配其他任何子路由时展示(类似于fallback占位)。
<Route path="invoices" element={<Invoices />}>
<Route
index
element={
<main style={{ padding: '1rem' }}>
<p>父级/invoices未匹配任何子路由时展示</p>
</main>
}
/>
<Route path=":invoiceId" element={<Invoice />} />
</Route>
6.新增Outlet组件,是子路由们渲染的容器。v5版本是在需要渲染子路由的位置定义子路由组件(即渲染和定义在一处),而v6是在定义父路由时直接定义好子路由,然后在需要渲染子路由的位置写上Outlet 容器组件。
// v5
import { Route, Link } from "react-router-dom";
export default function App() {
return (
<div>
<nav>
<Link to="/invoices">Invoices</Link>
<Link to="/expenses">Expenses</Link>
</nav>
{/* 定义好子路并且会在此渲染 */}
<Route path="expenses" component={Expenses} />
<Route path="invoices" component={Invoices} />
</div>
);
}
// v6
import { Outlet, Link } from "react-router-dom";
export default function App() {
return (
<div>
<nav>
<Link to="/invoices">Invoices</Link>
<Link to="/expenses">Expenses</Link>
</nav>
{/* 父路由中定义好的子路由将会在此渲染 */}
<Outlet />
</div>
);
}
8.特别重要: 凡是涉及到path、to等相关的写法,都类似于文件“相对路径”的写法,不再需要带上完整的父级路径,都是以当前自己的父级(如果存在)或以默认根路由 /
为相对基准,可以想象成命令行中的cd命令。
<Link to="../invoices">Invoices</Link>
<Link to="expenses">Expenses</Link>
<Route path="../../custom" element={<Custom />} />
<Route path="./relative" element={<Relative />} />
9.Route的path属性可以为"*",代表没有任何路径匹配时,类似404兜底展示。
<Route
path="*"
element={
<main style={{ padding: '1rem' }}>
<p>没有任何路径匹配时展示,注意不要和index属性搞混</p>
</main>
}
/>
10.Route的exact属性已变成默认行为,无需书写。
11.子路由的path全都是相对路径,不可以/
开头。
Uncaught Error: Absolute route path "/s2" nested under path "/mem" is not valid. An absolute child route path must start with the combined path of all its parent routes.