React Router v6 新特性及遷移指南


React Router v6 新特性及遷移指南


前言

18年初,React Router的主要開發人員創建一個名為Reach Router的輕量級替代方案。

原來是相互抗衡的,卻沒想React Router直接拿來合併(真香!)

React Router v6 新特性及遷移指南


目前 v6已是測試最後一版,估計新的特性不出意外就是下面這些了。

React Router v6 新特性及遷移指南


  1. <switch>重命名為<routes>。/<routes>/<switch>
  2. <route>的新特性變更。/<route>
  3. 嵌套路由變得更簡單。
  4. 用useNavigate代替useHistory。
  5. 新鉤子useRoutes代替react-router-config。
  6. 大小減少:從20kb到8kb

1. <switch>重命名為<routes>/<switch>

該頂級組件將被重命名。但是,其功能大部分保持不變(嗨,瞎折騰)。

<code>// v5
<switch>
<route><home>/<route>
<route><profile>/<route>
/<switch>

// v6
<routes>
<route>} />
<route>} />
/<routes>
複製代碼/<code>

2. <route>的新特性變更/<route>

component/render被element替代

總而言之,簡而言之。就是變得更好用了。

<code>import Profile from './Profile';

// v5
<route>
<route> path=":userId"
render={routeProps => (
<profile>
)}
/>


// v6
<route>} />
<route>} />
複製代碼/<route>/<code>

3. 嵌套路由變得更簡單

具體變化有以下:

  • <route> 已更改為接受子路由。/<route>
  • 比<route>和<route>更簡單的匹配規則。/<route>/<route>
  • <route> 路徑層次更清晰。/<route>

3.1 簡化嵌套路由定義

v5中的嵌套路由必須非常明確定義,且要求在這些組件中包含許多字符串匹配邏輯(活久見啊,終於意識到這個問題了。)


React Router v6 新特性及遷移指南


且看之前的處理:

<code>// v5
import {
BrowserRouter,
Switch,
Route,
Link,
useRouteMatch
} from 'react-router-dom';

function App() {
return (
<browserrouter>
<switch>
<route>
<route>
/<switch>
/<browserrouter>
);
}

function Profile() {
let { path, url } = useRouteMatch();

return (



<switch>
<route>
<myprofile>
/<route>
<route>
<othersprofile>
/<route>
/<switch>

);

}
複製代碼/<code>

而在v6中,你可以刪除字符串匹配邏輯。不需要任何useRouteMatch()!

<code>// v6
import {
BrowserRouter,
Routes,
Route,
Link,
Outlet
} from 'react-router-dom';

function App() {
return (
<browserrouter>
<routes>
<route>} />
<route>} />
/<route>/<routes>
/<browserrouter>
);
}

function Profile() {
return (



<routes>
<route>} />
<route>} />
/<routes>

);
}
複製代碼/<code>

當然,還有更酸爽的操作,直接在路由裡定義<route>的<route>,然後用接下來的一個新API:Outlet/<route>/<route>

3.2 新API:Outlet

這玩意兒,像極了{this.props.children},具體用法看以下例子:

<code>function App() {
return (
<browserrouter>
<routes>
<route>} />
<route>}>
<route>} />
<route>} />

/<routes>
/<browserrouter>
);
}

function Profile() {
return (


{/*
將直接根據上面定義的不同路由參數,渲染<myprofile>或<othersprofile>
*/}
<outlet>

)
}
複製代碼/<code>

3.3 多個<routes>

以前,我們只能 在React App中使用一個 Routes。但是現在我們可以在React App中使用多個路由,這將幫助我們基於不同的路由管理多個應用程序邏輯。

<code>import React from 'react';
import { Routes, Route } from 'react-router-dom';

function Dashboard() {
return (

Look, more routes!


<routes>
<route>} />
<route>} />
/<routes>

);
}

function App() {
return (
<routes>
<route>} />
<route>} />
/<routes>
);
}
複製代碼/<code>

4. 用useNavigate代替useHistory

從一目瞭然改到雙目失明。。。

總感覺React Router團隊有點兒戲。。。

<code>// v5
import { useHistory } from 'react-router-dom';

function MyButton() {
let history = useHistory();
function handleClick() {
history.push('/home');
};
return <button>Submit/<button>;
};
複製代碼/<code>

現在,history.push()將替換為navigation():

<code>// v6
import { useNavigate } from 'react-router-dom';

function MyButton() {
let navigate = useNavigate();
function handleClick() {
navigate('/home');
};
return <button>Submit/<button>;
};
複製代碼/<code>

history的用法也將被替換成:

<code>// v5
history.push('/home');
history.replace('/home');

// v6
navigate('/home');
navigate('/home', {replace: true});
複製代碼/<code>

5. 新鉤子useRoutes代替react-router-config。

感覺又是一波強行hooks,但還是相對於之前簡潔了一些。。。

<code>function App() {
let element = useRoutes([
{ path: '/', element: <home> },
{ path: 'dashboard', element: <dashboard> },
{ path: 'invoices',
element: <invoices>,
children: [
{ path: ':id', element: <invoice> },
{ path: 'sent', element: <sentinvoices> }
]
},
// 重定向
{ path: 'home', redirectTo: '/' },
// 404找不到

{ path: '*', element: <notfound> }
]);
return element;
}
複製代碼/<code>

6. 大小減少:從20kb到8kb

React Router v6給我們帶來方便的同時,還把包減少了一半以上的體積。。。


React Router v6 新特性及遷移指南


感覺可以去看一波源碼了。。。


React Router v6 新特性及遷移指南


7. 遷移及其它重要修復...

官方的遷移指南在這裡:React Router v6遷移指南

https://github.com/ReactTraining/react-router/blob/dev/docs/advanced-guides/migrating-5-to-6.md

其實上面所列的新特性,基本就是遷移的全部內容了。

基礎的起手式就是更新包:

<code>$ npm install react-router@6 react-router-dom@6
# or, for a React Native app
$ npm install react-router@6 react-router-native@6
複製代碼/<code>

其中我覺得特別需要注意的一點是:React Router v6使用簡化的路徑格,僅支持2種佔位符:動態:id樣式參數和*通配符

以下都是v6中的有效路由路徑:

<code>/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
/files-*
複製代碼/<code>

使用RegExp正則匹配的路徑將無效:

<code>/users/:id?
/tweets/:id(\\d+)
/files/*/cat.jpg
複製代碼/<code>

v6中的所有路徑匹配都將忽略URL上的尾部"/"。實際上,<route>已被刪除並且在v6中無效。這並不意味著您不需要使用斜槓。/<route>

在v5版本之前的路徑,存在路由歧義

  1. 當前路徑:"/users",則<link>將跳轉
  2. 當前路徑:"/users/",則<link>將跳轉

React Router v6修復了這種歧義,取消了尾部"/":

  1. 當前路徑:"/users",則<link>將跳轉
  2. 當前路徑:"/users",則<link>將跳轉

其形式更像命令行cd的用法:

<code>// 當前路徑為 /app/dashboard 

<link> // /<code>

結語

參考文章:

A Sneak Peek at React Router v6

What’s new in React Router v6

React Router v6 in Three Minutes Migrating

React Router v5 to v6

❤️ 看完三件事

如果你覺得這篇內容對你挺有啟發,我想邀請你幫我一個小忙:

  1. 點贊,讓更多的人也能看到這篇內容(收藏不點贊,都是耍流氓 -_-)


分享到:


相關文章: