ReactRouter v6升级的步骤

avatar
作者
筋斗云
阅读量:3

React Router v6 引入了一个 Routes 组件,它有点像 Switch ,但功能要强大得多。与 Switch 相比, Routes 的主要优势在于:

  • <Routes> 中的所有 <Route> 和 <Link> 都是相对的。这导致在 <Route path> 和 <Link to> 中的代码更精简和更可预测。
  • 路由的选择基于最佳匹配,而不是按顺序遍历。这避免了由于在 <Switch> 中定义较晚而导致无法到达的错误。
  • 路由可以嵌套在一个地方,而不是分散在不同的组件中。在中小型应用程序中,这样可以方便地一次性查看所有路由。在大型应用程序中,您仍然可以通过 React.lazy 动态加载将路由嵌套在打包中。

v6,您需要将所有 <Switch> 元素转换为 <Routes> 。

首先,让我们来谈谈 v6 中的相对路由和链接。

v5 是这样写:

// This is a React Router v5 app import {   BrowserRouter,   Switch,   Route,   Link,   useRouteMatch, } from "react-router-dom";  function App() {   return (     <BrowserRouter>       <Switch>         <Route exact path="/">           <Home />         </Route>         <Route path="/users">           <Users />         </Route>       </Switch>     </BrowserRouter>   ); }  function Users() {   // In v5, nested routes are rendered by the child component, so   // you have <Switch> elements all over your app for nested UI.   // You build nested routes and links using match.url and match.path.   let match = useRouteMatch();    return (     <div>       <nav>         <Link to={`${match.url}/me`}>My Profile</Link>       </nav>        <Switch>         <Route path={`${match.path}/me`}>           <OwnUserProfile />         </Route>         <Route path={`${match.path}/:id`}>           <UserProfile />         </Route>       </Switch>     </div>   ); }

v6需要这个样子:

// This is a React Router v6 app import {   BrowserRouter,   Routes,   Route,   Link, } from "react-router-dom";  function App() {   return (     <BrowserRouter>       <Routes>         <Route path="/" element={<Home />} />         <Route path="users/*" element={<Users />} />       </Routes>     </BrowserRouter>   ); }  function Users() {   return (     <div>       <nav>         <Link to="me">My Profile</Link>       </nav>        <Routes>         <Route path=":id" element={<UserProfile />} />         <Route path="me" element={<OwnUserProfile />} />       </Routes>     </div>   ); }

v5 应用程序中的所有 <Route children> 在 v6 中都变为了 <Route element={}>

对于子路由,index设置为true时,相当于一个默认的子路由

关于 <Route path> 模式的注意事项

React Router v6 使用简化的路径格式。在 v6 中, <Route path> 只支持两种占位符:动态 :id 样式的参数和 * 通配符。 * 通配符只能在路径末尾使用,不能在中间使用。

/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*

在 v6 中,无论当前 URL 如何, <Link to="me"> 都会呈现相同的 <a href> 。 

使用useRoutes代替react-router-config

v5 版本的 react-router-config 包中的所有功能都已移至 v6 的核心中。如果您喜欢/需要将路由定义为 JavaScript 对象,而不是使用 React 元素,那么您一定会喜欢这个功能。

function App() {   let element = useRoutes([     // These are the same as the props you provide to <Route>     { path: "/", element: <Home /> },     { path: "dashboard", element: <Dashboard /> },     {       path: "invoices",       element: <Invoices />,       // Nested routes use a children property, which is also       // the same as <Route>       children: [         { path: ":id", element: <Invoice /> },         { path: "sent", element: <SentInvoices /> },       ],     },     // Not found routes work as you'd expect     { path: "*", element: <NotFound /> },   ]);    // The returned element will render the entire element   // hierarchy with all the appropriate context it needs   return element; }

使用useNavigate代替useHistory

React Router v6 引入了新的导航 API,该 API 与 <Link> 同义,可更好地兼容启用了悬念的应用程序。根据您的风格和需求,我们提供了该 API 的命令式和声明式版本。

useHistory 更改为 useNavigate ,并更改 history.push 或 history.replace 调用站点。

// This is a React Router v6 app import { useNavigate } from "react-router-dom";  function App() {   let navigate = useNavigate();   function handleClick() {     navigate("/home");   }   return (     <div>       <button onClick={handleClick}>go home</button>     </div>   ); }

注意:请注意,v5 版 <Redirect /> 默认使用 replace 逻辑(可通过 push 属性进行更改),而 v6 版 <Navigate /> 默认使用 push 逻辑,可通过 replace 属性进行更改。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!