现代化 React 路由 Hookrouter 的使用

前端开发 @ 税友集团

现代化 React 路由 Hookrouter 的使用

11.jpg

路由在单页应用程序(SPA)页面中导航和初始化状态是至关重要的。对于 React,大多数开发者都使用过 react-router-dom,这是 Reactrouter 库用于路由的一个变量。

然而,随着 React hooks 的引入,最近一个被称为 Hookrouter 的新模块被推出,作为一个基于 hooks 的灵活、快速的路由。

本文将重点介绍我们如何使用 Hookrouter 模块来实现 Reactrouter 的基本功能。


为了演示 Hookrouter 的功能,我将使用一个商城作为示例,有四个基本组件,即 Nav.js、Home.js、About.js 和 Shop.js。此外,使用 Hookrouter 作为路由的完整 React 应用程序可以在这里找到。

1. 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 className="App">
      <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 className="App">
        <Nav/>
        {routeResults}
    </div>
  );
}

export default App;
复制代码

Reactrouter 中的 <Route/> 组件每次都必须被渲染,同时还有应用程序中每个路由的所有 props。然而,在 Hookrouter 中,定义为对象的路由可以简单地传递给 useRoutes() hook。

注意: 确保在组件之外创建路由对象;否则,整个对象将在每次渲染时被重新创建。

2. 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 className="App">
      <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 className="App">
        <Nav/>
        {routeResults||<h1>PAGE  NOT FOUND</h1>}
    </div>
  );
}

export default App;
复制代码

注意: 我发现一个重要事实是,在 Reactrouter <Switch> 中,如果没有明确指明路由导航,在某些情况下可能导致路由错误。

例如,如果到 {Home} 的路径没有明确指明,应用程序将不会导航到任何其他以 / 开头的路径。因此,应用程序不会路由导航到 {About}{Shop} 组件,而会一直路由导航到主页。然而,在 Hookrouter 中,由于路由是作为一个对象来声明的,所以不需要明确声明导航路径。

3. 使用 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
复制代码

4. 处理动态路由

一些组件包含动态部分,必须根据 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 参数的处理方式不同。

  1. 它使用路由对象中定义的键来读取 URL 参数。
  2. 将它们放入一个对象中,命名的参数将作为一个组合对象被转发给路由结果函数。
  3. 使用对象解构从中提取动态属性,然后可以应用于相关组件。

因此,正如你所看到的,使用 Reactrouter 获得的结果同样可以通过 Hookrouter 实现。

5. 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 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

文章分类
前端