Hookrouter 開發使用路由在單頁應用程式頁面中導航和初始化狀態是至關重要的。Hookrouter 模塊為處理 React 應用程式中的路由提供了一個更好方案。
原文地址:Hookrouter: A Modern Approach to React Routing本文永久連結:github.com/xitu/gold-m…校對者:PassionPenguin、KimYang路由在單頁應用程式(SPA)頁面中導航和初始化狀態是至關重要的。對於 React,大多數開發者都使用過 react-router-dom,這是 Reactrouter 庫用於路由的一個變量。
然而,隨著 React hooks 的引入,最近一個被稱為 Hookrouter 的新模塊被推出,作為一個基於 hooks 的靈活、快速的路由。
本文將重點介紹我們如何使用 Hookrouter 模塊來實現 Reactrouter 的基本功能。
為了演示 Hookrouter 的功能,我將使用一個商城作為示例,有四個基本組件,即 Nav.js、Home.js、About.js 和 Shop.js。此外,使用 Hookrouter 作為路由的完整 React 應用程式可以在這裡找到。
Hookrouter 與 Reactrouter 定義路由對比當使用 Reactrouter 時,我們可以按以下方式定義路由。
import Nav from './components/Nav';
import About from './components/About';
import Shop from './components/Shop';
import Home from './components/Home';
import {BrowserRouter as Router,Route} from'react-router-dom';
function App() {
return (
<Router>
<div class>
<Nav/>
<Route path = '/' component = {Home}/>
<Route path = '/about' component = {About}/>
<Route path = '/shop' component = {Shop}/>
</div>
</Router>
);
}
export default App;
複製代碼我希望大家都能熟悉上述這些相對簡單的示例。
如果我們使用 Hookrouter 來實現,那麼可以使用 useRoutes() hook 將路由聲明為一個對象。
對象的鍵定義了路徑,而對象的值是路徑匹配時觸發的函數。路由器一個接一個地檢查路徑,在找到匹配後停止檢查。
import {useRoutes} from 'hookrouter'
import Nav from './components/Nav';
import About from './components/About';
import Shop from './components/Shop';
import Home from './components/Home';
function App() {
const routes = {
'/' :()=><Home/>,
'/about' :()=> <About/>,
'/shop' :()=> <Shop/>,
};
const routeResults = useRoutes(routes);
return (
<div class>
<Nav/>
{routeResults}
</div>
);
}
export default App;
複製代碼Reactrouter 中的 <Route/> 組件每次都必須被渲染,同時還有應用程式中每個路由的所有 props。然而,在 Hookrouter 中,定義為對象的路由可以簡單地傳遞給 useRoutes() hook。
注意: 確保在組件之外創建路由對象;否則,整個對象將在每次渲染時被重新創建。
Hookrouter 實現 Reactrouter 開關功能<Switch> 是用來渲染路由的,只渲染與位置相匹配的第一個孩子 <Route> 或 <Redirect>。當定義的導航路由不匹配時,<Switch> 通常被用來呈現 404 頁面。
讓我們來看看如何使用 <Switch> 來用 Reactrouter 路由呈現 404 頁面。
import Nav from './components/Nav';
import About from './components/About';
import Shop from './components/Shop';
import Home from './components/Home';
import Error from './components/Error';
import {BrowserRouter as Router, Switch,Route} from'react-router-dom';
function App() {
return (
<Router>
<div class>
<Nav/>
<Switch>
<Route path = '/' exact component = {Home}/>
<Route path = '/about' component = {About}/>
<Route path = '/shop'exact component = {Shop}/>
<Route><Error/> </Route>
</Switch>
</div>
</Router>
);
}
export default App;
複製代碼當使用 Hookrouter 進行路由時,由於路由是在一個對象中定義的,所以需要專門渲染,useRoutes() hook 在默認情況下執行 <Switch> 組件的功能。
例如,使用 Hookrouter 路由呈現 404 頁面,我們只需傳遞我們想要顯示的錯誤或包含錯誤信息的組件進行渲染,如下所示(第 17 行)。
import {useRoutes} from 'hookrouter'
import Nav from './components/Nav';
import About from './components/About';
import Shop from './components/Shop';
import Home from './components/Home';
function App() {
const routes = {
'/' :()=><Home/>,
'/about' :()=> <About/>,
'/shop' :()=> <Shop/>,
};
const routeResults = useRoutes(routes);
return (
<div class>
<Nav/>
{routeResults||<h1>PAGE NOT FOUND</h1>}
</div>
);
}
export default App;
複製代碼注意: 我發現一個重要事實是,在 Reactrouter <Switch> 中,如果沒有明確指明路由導航,在某些情況下可能導致路由錯誤。
例如,如果到 {Home} 的路徑沒有明確指明,應用程式將不會導航到任何其他以 / 開頭的路徑。因此,應用程式不會路由導航到 {About} 或 {Shop} 組件,而會一直路由導航到主頁。然而,在 Hookrouter 中,由於路由是作為一個對象來聲明的,所以不需要明確聲明導航路徑。
通過 Reactrouter 使用 <Link> 來在整個應用中導航。此外,在 React 應用中,可以用它來定製和交互式地管理導航。
import React from 'react'
import {Link} from 'react-router-dom'
function Nav() {
return (
<div>
<nav>
<ul className='nav-links'>
<Link className='Link' to='/'>
<li>HOME</li>
</Link>
<Link className='Link' to='/about'>
<li>ABOUT</li>
</Link>
<Link className='Link' to='/shop'>
<li>SHOP</li>
</Link>
</ul>
</nav>
</div>
)
}
export default Nav
複製代碼Hookrouter 使用一個 <A> 組件來提供 <Link> 組件的功能。<A> 是一個來自 HTML 的 <a> 標記的包裝器,與錨標記的功能完全兼容。
<A> 和 <Link> 之間的主要區別是,<A> 將 URL 推送到歷史棧,而不加載新的頁面。因此,onclick 函數必須由 <A> 組件包裝,以攔截點擊事件,停止默認行為並將 URL 推送到歷史堆棧。
import React from 'react'
import {A} from 'hookrouter'
function Nav() {
return (
<div>
<nav>
<ul className='nav-links'>
<A className='Link' href='/'>
<li>HOME</li>
</A>
<A className='Link' href='/about'>
<li>ABOUT</li>
</A>
<A className='Link' href='/shop'>
<li>SHOP</li>
</A>
</ul>
</nav>
</div>
)
}
export default Nav
複製代碼一些組件包含動態部分,必須根據 URL 的要求進行渲染。URL 參數被用來在 URL 中設置動態值。在 Reactrouter 中,佔位符被傳遞給 <Route/> 組件中以冒號開始的路徑道具。
為了證明這個判斷,讓我們考慮在應用程式的商店頁面上顯示一個產品列表。當用戶點擊某個特定產品時,他們應該被引導到該產品的詳細信息頁面。導航是動態進行的,在路徑道具中傳遞產品 ID 作為佔位符。
<Route path = '/shop/:id' component = {Details}/>
複製代碼在 Hookrouter 中,URL 參數的傳遞方式與 Reactrouter 中的方式相同,結構也是一樣的。
const routes = {
'/shop/:id':({id})=><Details id={id}/>
};
複製代碼然而,Hookrouter 對 URL 參數的處理方式不同。
將它們放入一個對象中,命名的參數將作為一個組合對象被轉發給路由結果函數。使用對象解構從中提取動態屬性,然後可以應用於相關組件。因此,正如你所看到的,使用 Reactrouter 獲得的結果同樣可以通過 Hookrouter 實現。
程序化導航使用 Hookrouter 依賴包的 navigate(url, [replace], [queryParams]) 函數,可以用來將用戶發送到一個提供的絕對或相對 URL 定義的特定頁面。例如,要導航到關於頁面,可以使用下面的代碼片段。
navigate(『/about』)
複製代碼navigate() 默認是一個向前的導航。因此,將在瀏覽歷史中創建一個新的條目,用戶可以點擊瀏覽器中的後退按鈕,回到前一頁。
重定向Hookrouter 藉助於 useRedirect() hook 來處理重定向問題。它需要一個源路由和一個目標路由作為參數。
useRedirect('/', '/greeting');
複製代碼每當 / 路徑被匹配,useRedirect() 將自動將用戶重定向到 /greeting 路徑。
這個 hook 會觸發一個替換的路由導航。因此,在導航歷史中,將只有一個條目。因此,如果重定向從 / 發生到 /greeting,如最後一個代碼片斷所示, / 路線將不會出現在瀏覽歷史中。
許多其他 Reactrouter 庫的功能(除了這裡討論的那些)可以使用 Hookrouter 模塊實現,如嵌套路由、懶加載組件和伺服器端渲染。
此外,請隨時查看 Hookrouter 文檔,了解更多關於這個模塊的信息。
不足之處我注意到,有時 Hookrouter 在最新版本默認啟用嚴格模式的 create-react-app 中無法工作。
然而,你只需要從 index.js 中刪除 <React.StrictMode> 組件就可以使用 Hookrouter。
<React.StrictMode>
<App />
</React.StrictMode>
複製代碼另一個缺點是,由於這個模塊相對較新。它可能包含一些未知的和不尋常的錯誤,從而導致發生意外結果。
本文總結從上面的示例可以看出,Hookrouter 模塊為處理 React 應用程式中的路由提供了一個更簡潔、更快速、更靈活的選擇。
它提供了 Reactrouter 庫的大部分功能。因此,我鼓勵你去嘗試一下,先在小型項目中使用它。
謝謝你的閱讀!
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社區,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。