React Router V5 与 V6
React Router 版本 6 最近发布,了解其变化对我们来说很重要,因为它是目前使用最广泛的 React 库之一。
那么什么是 React Router?
React Router 是一个功能齐全的客户端和服务器端路由库,适用于 React,它是一个用于构建用户界面的 JavaScript 库。React Router 可以在任何支持 React 的地方运行:Web 平台、使用 Node.js 的服务器以及 React Native。
V6 版本进行了大量底层改进,例如增强了路径模式匹配算法,添加了新的组件。不仅如此,打包体积也减少了近 58%。
因此,您可以进行以下一些更改以将现有项目从 React Router v5 升级到 v6。
Switch
替换为Routes
在 v6 中,Switch
in 不再从 导出react-router-dom
。在早期版本中,我们可以使用Switch
来包装路由。现在,我们可以使用Routes
来代替 ,从而实现相同的功能Switch
。
我们定义自己的方式发生了变化Route
匹配路由时应渲染的组件不能写为Route
组件的子项,但它需要一个名为的 prop,element
我们必须传递一个 JSX 组件才能渲染它。
exact
不再需要道具
在版本 6 中,React Router 变得更加出色。现在更好的路径匹配算法使我们能够在不使用exact
prop 的情况下匹配特定的路由。以前,如果没有 prop exact
,任何以相关关键字开头的 URL 都会被加载,因为匹配过程是按照路由定义从上到下进行的。但现在,我们不必担心这一点,因为 React Router 拥有更完善的算法来为特定 URL 加载最佳路由,定义的顺序现在不再重要。
因此,总结这三点,我们可以考虑这个代码片段。
在 v5 中
import { Switch, Route } from "react-router-dom";
.
.
.
<Switch>
<Route path="/">
<Home/>
</Route>
<Route exact path="/cryptocurrencies">
<Cryptocurrencies/>
</Route>
<Route exact path="/crypto/:coinId">
<CryptoDetails/>
</Route>
<Route exact path="/exchanges">
<Exchanges />
</Route>
</Switch>
在 v6 中
import { Routes, Route } from "react-router-dom";
.
.
.
<Routes>
<Route path="/" element={<Home />} />
<Route path="/crypto/:coinId" element={<CryptoDetails />} />
<Route path="/cryptocurrencies" element={<Cryptocurrencies />} />
<Route path="/exchanges" element={<Exchanges />} />
</Routes>
无需react-router-config
单独安装
react-router-config
允许我们将路由定义为 javascript 对象,而不是 React 元素,并且它的所有功能都必须移至核心 react router v6 中。
//V5
import { renderRoutes } from "react-router-config";
const routes = [
{
path: "/",
exact: true,
component: Home
},
{
path: "/cryptocurrencies",
exact: true,
component: Cryptocurrencies
},
{
path: "/exchanges",
exact: true,
component: Exchanges
}
];
export default function App() {
return (
<div>
<Router>{renderRoutes(routes)}</Router>
</div>
);
}
//V6
function App() {
let element = useRoutes([
// These are the same as the props you provide to <Route>
{ path: "/", element: <Home /> },
{ path: "/cryptocurrencies", element: <Cryptocurrencies />,
// Nested routes use a children property
children: [
{ path: ":coinId", element: <CryptoDetails /> },
]
},
{
path: "/exchanges",
element: <Exchanges />
},
]);
// The returned element will render the entire element
// hierarchy with all the appropriate context it needs
return element;
}
useHistory
现在是useNavigate
React Router v6 现在具有 navigate api,大多数时候这意味着替换useHistory
为useNavigate
。
//V5
import { useHistory } from "react-router-dom";
function News() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<div>
<button onClick={()=>{
history.push("/home");
}}>Home</button>
</div>
);
}
//V6
import { useNavigate } from "react-router-dom";
function News() {
let navigate = useNavigate();
return (
<div>
<button onClick={()=>{
navigate("/home");
}}>go home</button>
</div>
);
}
一些更常见的功能useHistory
包括go
、goBack
和goForward
。这些功能也可以通过 navigate API 实现,我们只需要指定想要前进或后退的步数(“+”表示前进,“-”表示后退)。因此,我们可以将这些功能编写成代码,并考虑这一点。
//V5
import { useHistory } from "react-router-dom";
function Exchanges() {
const { go, goBack, goForward } = useHistory();
return (
<>
<button onClick={() => go(-2)}>
2 steps back
</button>
<button onClick={goBack}>1 step back</button>
<button onClick={goForward}>1 step forward</button>
<button onClick={() => go(2)}>
2 steps forward
</button>
</>
);
}
//V6
import { useNavigate } from "react-router-dom";
function Exchanges() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>
2 steps back
</button>
<button onClick={() => navigate(-1)}>1 step back</button>
<button onClick={() => navigate(1)}>
1 step forward
</button>
<button onClick={() => navigate(2)}>
2 steps forward
</button>
</>
);
}
activeStyle
和activeClassName
道具移除<NavLink />
在之前的版本中,我们可以为链接的激活时间设置一个单独的类名或样式对象<NavLink/>
。在 V6 中,这两个属性被移除了,对于导航链接的 className 和 style 属性,它们的工作原理略有不同。它们接受一个函数,该函数会提供一些关于链接的信息,以便我们更好地控制样式。
//V5
<NavLink
to="/news"
style={{ color: 'black' }}
activeStyle={{ color: 'blue' }}>
Exchanges
</NavLink>
<NavLink
to="/news"
className="nav-link"
activeClassName="active">
Exchanges
</NavLink>
//V6
<NavLink
to="/news"
style={({isActive}) => { color: isActive ? 'blue' : 'black' }}>
Exchanges
</NavLink>
<NavLink
to="/news"
className={({ isActive }) => "nav-link" + (isActive ? "active" : "")}>
Exchanges
</NavLink>
替换Redirect
为Navigate
Redirect
不再从 导出react-router-dom
,而是使用 canNavigate
来实现相同的功能。
//V5
import { Redirect } from "react-router-dom";
<Route exact path="/latest-news">
<Redirect to="/news">
</Route>
<Route exact path="/news">
<News />
</Route>
//V6
import { Navigate } from "react-router-dom";
<Route path="/latest-news" element={<Navigate replace to="/news">} />
<Route path="/news" element={<Home />} />
请注意在中传递的replace
prop 。这表示我们正在替换当前的导航堆栈。如果没有它,就意味着我们只是将组件推送到现有的导航堆栈中。element
Route
replace
今天就到这里。希望这能帮助你将你的 React 项目升级到 React Router V6。
谢谢阅读!!😇😇祝您
编码愉快!!祝您构建愉快!!