React Hook Router一个现代的React Router替代方案

图片

React Hooks如何替代React Router的免费翻译。
Peter Ekene Eze发表。

自从React Hooks问世以来,发生了很多变化。 钩子提供的机会使我们可以重新考虑对React中某些概念的方法,包括路由。

该帖子绝不打算被React Router取消或轻描淡写。 我们将探索其他可能性,并了解如何使用挂钩通过React应用程序改进路由。

为此,我们将React Router和hooksrouter与示例进行比较。 首先,让我们仔细看一下React Router。

反应路由器


React Router是一种在React应用程序中管理路由的流行声明方式。 它减少了为应用程序中所有页面和屏幕手动配置路由所涉及的工作量。 React Router为我们提供了三个主要组件来帮助我们进行路由-Route,Link和BrowserRouter。

在React Router中路由


想象我们正在创建一个三页的React应用程序。 通常我们使用React Router进行路由并编写如下代码:

import Users from "./components/Users"; import Contact from "./components/Contact"; import About from "./components/About"; function App() { return ( <div> <Router> <div> <Route path="/about" component={About} /> <Route path="/users" component={Users} /> <Route path="/contact" component={Contact} /> </div> </Router> </div> ); } 

从React Router软件包中导入的<Route />组件接受两个参数:用户遵循的路径,以及沿指定路径显示的组件。

钩子作为替代路由


hookrouter模块导出useRoutes()钩子,该钩子检查预定义的路由对象并返回结果。 在路由对象中,将路由定义为键,并将其值定义为在路由匹配时将调用的函数。 挂钩上的示例代码:

 import Users from "./components/Users"; import Contact from "./components/Contact"; import About from "./components/About"; const Routes = { "/": () => , "/about": () => , "/contact": () => }; export default Routes; 

这种写路线的方式更具吸引力。 怎么了 因为我们不需要做很多工作。 使用React Router,我们必须为应用程序中的所有单个路由呈现<Route />组件。 更不用说我们传递给他的所有参数了。 使用钩子,我们可以通过简单地将它们传递给useRoutes()钩子来使用路由:

 import {useRoutes} from 'hookrouter'; import Routes from './router' function App() { const routeResult = useRoutes(Routes) return routeResult } 

这为我们提供了与使用React Router时完全相同的结果,但实现起来更干净,更容易。

反应路由器导航


React Router包含一个<Link />组件,可帮助我们自定义应用程序导航和管理交互式路由。 我们有一个包含三页的应用程序,让我们在屏幕上显示它们并在按下时继续前进:

 import { Route, Link, BrowserRouter as Router } from "react-router-dom"; import Users from "./components/Users"; import Contact from "./components/Contact"; import About from "./components/About"; function App() { return ( <div className="App"> <Router> <div> <ul> <li> <Link to="/about">About</Link> </li> <li> <Link to="/users">Users</Link> </li> <li> <Link to="/contact">Contact</Link> </li> </ul> <Route path="/about" component={About} /> <Route path="/users" component={Users} /> <Route path="/contact" component={Contact} /> </div> </Router> </div> ); } 

我们创建了从应用程序的一页到另一页所需的导航。 这是一个很好的例子。



我们使用挂钩进行导航


hookrouter模块在HTML <a/>标记上提供了<A/>包装器。 它可以作为react组件使用,并且与本地<a/>标签100%兼容。 唯一的区别是,它将导航移动到历史记录堆栈上,而不是实际加载新页面。

 const routes = { "/user": () => <Users />, "/about": () => <About />, "/contact": () => <Contact /> }; function App() { const routeResult = useRoutes(routes); return ( <div className="App"> <A href="/user">Users Page</A> <A href="/about">About Page</A> <A href="/contact">Contacts Page</A> {routeResult} </div> ); } 



软件导航


hookrouter模块使我们能够访问navigation()钩子,我们可以将URL传递到该钩子,它将用户重定向到该URL。 每次对navigation()函数的调用都代表一个前向导航,因此,用户可以在浏览器中单击后退按钮以返回到上一个URL。 默认情况下会发生这种情况。

 navigate('/user/'); 

但是,如果您需要其他行为,则可以在浏览器历史记录中进行替换。 navigation()挂钩接受三个参数-Navigation(URL,[replace],[queryParams]),第二个参数用于更改替换行为。 它将删除当前的历史记录条目,并将其替换为新的历史记录条目。 要实现此效果,只需将其参数设置为true。

 navigate('/user', true); 

反应路由器交换机


当某些路由不匹配时,React Router使用<Switch />组件显示默认页面。 通常,它会显示页面404,以通知用户应用程序中未定义所选路线。 为此,我们将所有路由包装在<Switch />组件内,并绘制404页面,而无需为其定义文件路径:

 import { Route, Link, BrowserRouter as Router, Switch } from "react-router-dom"; import Users from "./components/Users"; import Contact from "./components/Contact"; import Home from "./components/About"; import NoPageFound from "./components/NoPageFound.js"; function App() { return ( <div className="App"> <Router> <div> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/users">Users</Link> </li> <li> <Link to="/contact">Contact</Link> </li> </ul> <Switch> <Route exact path="/" component={Home} /> <Route path="/users" component={Users} /> <Route path="/contact" component={Contact} /> <Route component={NoPageFound} /> </Switch> </div> </Router> </div> ); } 

因此,当切换到未定义的路由时,React Router将显示NoPageFound组件。 这样,我们可以在导航应用程序时通知用户他们的位置以及发生的情况。

钩上的备用开关


由于我们定义了包含所有路由的路由对象,并将该对象简单地传递给useRoutes()挂钩,因此按条件显示路由变得非常容易。 如果在未定义所选路线时定义默认的NoPageFound组件以进行渲染,则只需将该文件与结果函数一起传递即可,如下所示:

 import { useRoutes, A } from "hookrouter"; import routes from "./router"; import NoPageFound from "./components/NoPageFound"; function App() { const routeResult = useRoutes(routes); return ( <div className="App"> <A href="/user">Users Page</A> <br /> <A href="/about">About Page</A> <br /> <A href="/contact">Contacts Page</A> <br /> {routeResult || <NoPageFound />} </div> ); } 



与在默认情况下使用React Router中的组件呈现页面相比,它看起来更干净,更易读。

反应路由器重定向


当我们想动态地将用户从一条路由引导到另一条路由时,就会发生重定向。 例如,在授权过程中,当用户成功登录时,我们希望将其从路径“ /登录”重定向到路径“ /仪表板”。

使用React Router,我们可以通过几种方式来做到这一点-使用历史对象或<Redirect />组件。 例如,如果我们有一个登录表单,则可以使用浏览器历史记录对象在登录时将用户重定向到“ /仪表盘”路线:

 import React from 'react' class Login extends React.Component { loginUser = () => { // if (user is logged in successfully) this.props.history.push('/dashboard') } render() { return ( <form> <input type="name" /> <input type="email" /> <button onClick={this.loginUser}>Login</button> </form> ) } } export default Login 

挂钩重定向


hookrouter模块为我们提供了useRedirect()挂钩,该挂钩可以将源路由和目标路由作为参数。

 useRedirect('/user', '/dashboard'); 

找到“ /用户”路径后,这将自动将用户重定向到“ /仪表盘”路由。 例如,如果我们不想显示任何用户,而是自动将用户重定向到他的/仪表板,则将其编写为:

 import {useRoutes, useRedirect} from 'hookrouter'; import dashboard from "./components/Dashboard"; const routes = { '/home': () => <Users />, '/dashboard': () => <Dashboard /> }; const Users = () => { useRedirect('/user', '/dashboard'); const routeResult = useRoutes(routes); return routeResult } 



值得注意的是,useRedirect()挂钩会导致导航历史记录的替换。 结果,导航历史记录中将只有一个条目。 这意味着,如果从“ /用户”重定向到“ /仪表板”(如所考虑的最后一个代码片段中的情况一样),则路径“ /用户”将不会显示在浏览历史记录中。 我们只有'/仪表盘'路线。

在React Router中处理URL参数


URL参数帮助我们根据组件的动态URL显示它们。 这与嵌套路由类似,但是在这种情况下,路由不会更改,但会被更新。

例如,如果我们的应用程序中有不同的用户,则可以使用各自的路由(例如“ user / user1 //”和“ users / user2 //”等)分别识别用户。 为此,我们需要使用URL参数。 在React Router中,我们只需在<Route />组件的path属性中传递一个以冒号开头的参数(例如id):

 <Route path="users/:id" component={Users} /> 

使用挂钩处理URL参数


在hookrouter和React Router中,URL参数的处理几乎没有区别。 设计是相同的(即,您可以使用冒号和参数名称将URL参数传递给目标路由)。

但是,hookrouter的工作方式有所不同。 它将读取所有URL参数并将其放置在对象中。 这是使用在routes对象中定义的键完成的。 然后,所有命名的参数将作为组合对象重定向到路线的结果函数。

 const routes = { '/user/:id': ({id}) => <User userId={id} /> } 

使用对象的解构,我们只需从props对象获取id属性,然后将其应用于我们的组件。 因此,我们得到的结果与React Router完全相同。

结论


我们研究了React应用程序中的另一种路由方法。 React Router是一个很棒的工具,但是,随着React中的钩子的到来,包括路由如何工作在内的很多变化。 这个基于挂钩的模块提供了一种更灵活,更干净的方式来处理小型项目中的路线。

除了文章中讨论的主要功能外,Hookrouter还具有许多其他功能,例如:

  • 延迟加载组件
  • 嵌套路线
  • 将其他数据传输到路线
  • 导航拦截
  • 服务器渲染支持

hookrouter项目具有出色的文档,您可以在其中快速找到感兴趣的问题。

本文使用了hookrouter 文档中的材料
以及原始的《 React Hooks如何取代React Router》一文。

Git存储库Hookrouter

UPD:完成本文时,我没有立即看到您可以选择出版物“翻译”的类型,我向读者表示歉意,并在标题中填写了指向原文的链接并指出了作者。

Source: https://habr.com/ru/post/zh-CN459434/


All Articles