React-routerreact js 中路由的规范库。它容许 React 应用程序的用户在应用程序的不同局部(组件)之间挪动。

react-router 团队 发表将 在 2021 年底公布react-router 版本 6 (v6) 的稳固版本,但因为一些重大的 API 更改,从 react-router 版本 5 (v5) 切换到 v6 可能会很艰难. 在本文中,咱们将介绍 v6 中的新性能以及如何将现有的 React 我的项目从 v5 降级到 v6

要在咱们的应用程序中降级 react-router 包的版本,咱们导航到我的项目文件夹并运行

npm install react-router-dom@[VERSION_NUMBER]

替换VERSION_NUMBER为咱们要装置的版本,或者如果咱们想要最新版本,则替换为“ latest ”,如下所示:

npm install react-router-dom@6

或者

npm install react-router-dom@latest

请留神,咱们必须连贯到互联网能力实现装置,否则装置将失败。另外,请确保我的项目中的 react 版本是 v16.8 或更高版本,因为 react-router v6 重大依赖于 react v16.8 最后反对的钩子

Switch 被替换为 Routes

v5 时代的第一个被代替的是Switch组件。该Switch组件用于包装咱们的路由,它确保每次只加载一个匹配的路由。但这在 v6 中不再存在。咱们应用Routes组件来替换Switch。请留神,咱们依然须要导入BrowserRouter包装咱们的应用程序,就像在 v5 中所做的那样。

在 v5 中,咱们是这样做:

import { BrowserRouter, Switch } from "react-router-dom";function App() {    return (        <BrowserRouter>            <div className="App">                <Switch>                    {" "}                    {/* 路由Route在此定义 */}                </Switch>            </div>        </BrowserRouter>    );}export default App

但在 v6 中,咱们将这样做

import { BrowserRouter, Routes } from "react-router-dom";function App() {    return (        <BrowserRouter>            <div className="App">                <Routes>                    {" "}                    {/* Switch 会被改成 Routes */}                    {/* 路由Route在此定义 */}                </Routes>            </div>        </BrowserRouter>    );}export default App

Route组件应用更新

只管该Route组件在 v6 中依然保留一个地位,但咱们定义它的应用形式与咱们在 v5 中的形式不同。咱们将不再以 v5 中的任何形式搁置咱们想要渲染的组件,而是对立将其作为elementprop的值传递。

没有exact配置

v5 中,不增加exact作为Route组件props的话,如果 URL 以 path 关键字结尾,则门路将匹配,因为匹配过程是从上到下的程序。但在 v6 中,咱们将不再须要该exact配置,因为门路模式匹配算法已更改,并且当初更加加强。

在 v5 中,咱们这样做了:

<Switch>   {/* 三种Route组件应用定义 */}   <Route path="/signup" component={Product} />   {/* 或 */}   {/* 这个办法容许咱们将 props 传递给渲染的组件 */}   <Route path="/games">       <Product id={2} />   </Route>   {/* 或是通过render函数 */}   <Route path="/games" render={(props) => <Product {...props} />} /></Switch>

在 v6 中,

<Routes>   {" "}   <Route path="/games" element={<Product />} />   {/* 带有props的渲染组件 */}   <Route path="/movies" element={<Product id={200} category="shirt" />} /></Routes>

Links 和 NavLinks

LinkNavLink组件依然能够运行在V6。Link组件应用与在 v5 的时候放弃一样,但应用NavLink组件时,删除了activeClassNameactiveStyle prop。在 v5 中,activeClassNameprop 用于在链接激活后主动将一些 CSS 类利用于链接,同时activeStyle容许咱们在链接激活时向链接增加外部款式。

然而在 v6 中,咱们当初能够应用一个函数来获取无关链接活动状态的信息。该函数的参数是一个具备属性的对象isActive。此属性在链接处于活动状态时为,在非流动时为isActive的值容许咱们应用条件表达式来批示流动款式或类名。

在 v5 中,咱们这样做了:

import {NavLink} from “react-router-dom”{/* … */}<NavLink   to="/product"   style={{ color: "#689" }}   activeStyle={{ color: "#3072c9" }}   className="nav_link"   activeClassName="active">   Products</NavLink>

但在 v6 中,咱们将这样做:

<NavLink   to="/product"   style={({ isActive }) => ({ color: isActive ? "#3072c9" : "#689" })}   className={({ isActive }) => `link${isActive ? " active" : ""}`}>   Product</NavLink>

Navigate代替Redirect

在 v5 中,咱们应用该Redirect组件将一个页面带到另一个页面,但它不再从 v6 中的 react-router-dom 导出。它已被Navigate组件替换。

在 v5 中,咱们这样做了:

<Route path="/faq">   <Redirect to="/about" /></Route><Route path="/about" component={About} />

但在 v6 中,咱们将这样做:

<Route path="/games" element={<Navigate to="/about" />} />;<Route path="/games" element={<About />} />;

须要留神的是,如果咱们只是依照Navigate下面代码片段中的形式增加组件,它只会将导航到该门路的导航推送到导航堆栈中,然而如果咱们打算用新页面替换以后页面,咱们将 replace 属性增加到Navigate组件中,如下所示:
<Route path="/games" element={<Navigate replace to="/about" />} />;

嵌套路由

顾名思义,嵌套路由是搁置在另一个路由中的路由。它们用于在子组件中出现更具体的信息。在 v6 中,咱们将嵌套路由搁置为父路由的子路由。而后咱们引入Outlet组件,它是从渲染组件中的 react-router-dom 导出的,用于指定咱们心愿嵌套信息显示在哪里。Outlet 组件不是必须的,但它使代码更清晰。
在 v5 中,咱们这样做了:

import { useRouteMatch } from "react-router-dom";function App() {   return (       <BrowserRouter>           <Switch>               <Route exact path="/about" component={About} />               <Route path="/product" component={Product} />           </Switch>       </BrowserRouter>   );}function Product() {   let match = useRouteMatch();   return (       <div>           <Switch>               {/* match.path 返回父路由中指定的门路。在这种状况下,它是“/product" */}               <Route path={`${match.path}`}>                   <AllProducts />               </Route>               {/* 匹配 /product/:id */}               <Route path={`${match.path}/:id`}>                   <ProductDetail />               </Route>           </Switch>       </div>   );}

在 v6 中,咱们这样做:

import { Outlet } from "react-router-dom";function App() {   return (       <Routes>           <Route path="/about" element={<About />} />           <Route path="/product" element={<Product />}>               {/* 这里嵌套路由的门路是绝对于父路由的门路的。 */}               {/* 这里变成 "/product/" */}               <Route path="/" element={<AllProducts />} />               {/* 这里变成 "/product/:id" */}               <Route path="/:id" element={<ProductDetail />} />           </Route>       </Routes>   );}function Product() {   return (       <Container>           <>               <div>Product</div>               {/* 父组件的其余内容 */}           </>           {/* 这是嵌套信息开始的中央 */}           <Outlet />       </Container>   );}

程序化导航

当用户因门路上产生的事件(例如单击按钮、API 申请实现等)而被重定向时,就会产生程序化导航。在 v5 中,咱们能够应用useHistory钩子来执行以下操作:

import { useHistory } from "react-router-dom";function Product() {   const history = useHistory();   const handleClick = () => {       //这会将新路线推送到导航堆栈的顶部       history.push("/new-route");       //这会将以后路线替换为导航堆栈中的新路由       history.replace("/new-route");   };   return (       <div>           <button>点击我重定向到新路由</button>       </div>   );}

然而在 v6 中,useHistoryhook 被替换为useNavigatehook,并且咱们以不同的形式应用它。

import { useNavigate } from "react-router-dom";function Product() {   const navigate = useNavigate();   const handleClick = () => {       //这会将新路线推送到导航堆栈的顶部       navigate("/new-route");       //这会将以后路线替换为导航堆栈中的新路由       navigate("/new-route", { replace: true });   };   return (       <div>           <button>点击我重定向到新路由</button>       </div>   );}

一件很酷的事件是咱们能够在导航堆栈上任意后退和后退。通过应用负数作为上述参数navigate(),路由会向前挪动该步数。正数向后做同样的事件

// Goes forwardnavigate(1)// Goes forward twicenavigate(2)// Goes backwardnavigate(-1)// Goes backward three timesnavigate(-3)

删除Prompt组件

Prompt如果有未保留的更改,v5 中的组件可避免意外来到页面。然而 react-router 团队并没有将它蕴含在 v6 中,也没有代替计划。因而,如果你须要该性能,你能够手动实现它或返回到 v5。

除了不包含Prompt在以后版本(v6)中,useBlockerusePrompt都不起作用。react-router 团队尽管在官网文档中示意,他们目前正在致力将其增加回 v6,但不是针对 6.x 的第一个稳固版本。

概括

让咱们强调一下咱们所经验的变动。

  • Switch 组件替换为 Routes 组件。
  • 如何搁置 Route 的渲染组件的更改。
  • 路由中没有exact。
  • activeClassName和activeStyle不存在于NavLink组件了.
  • 咱们能够通过函数回调拜访 NavLink 组件的 isActive 状态。
  • Redirect组件已替换为Navigate组件。
  • 实现嵌套路由的一种更时尚的形式。
  • 没有Prompt组件

总之,如果你还没有筹备好从 v5 或任何其余版本切换到 v6,你能够持续应用它装置以前的版本。

npm install react-router-dom@[VERSION_NUMBER]

然而,你将错过 v6 附带的一些好货色,包含但不限于:

  • 加强的门路模式匹配算法。
  • 依据Bundlephobia,体积大小缩小了 60%
  • 我置信咱们可能胜利地切换到 react-router v6 并停止使用 Switch 组件(双关语十分无意)。

    领有更杰出的编码体验。