📜 ⬆️ ⬇️

React Hook Router is a modern alternative to React Router.

image

A free translation of the publication How React Hooks can replace React Router .
Posted by Peter Ekene Eze.

Since the advent of React Hooks, much has changed. The opportunities provided by the hooks allowed us to review our approach to certain concepts in React, including routing.
')
This post is in no way intended to debit or diminish its importance. We will explore other features and see how we can improve routing in React applications using hooks.

To this end, we compare React Router and hooksrouter with illustrative examples. First, let's take a closer look at the React Router.

React Router


React Router is a popular declarative way to manage routes in React applications. It reduces the amount of work involved in manually setting routes for all pages and screens in the application. React Router provides us with three main components that help us do the routing - Route, Link and BrowserRouter.

Routing in React Router


Imagine that we are creating a React application consisting of three pages. Usually for routing we use React Router and write something like this:

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> ); } 

The <Route /> component imported from the React Router package takes two parameters: the path that the user follows, and the component to display along the specified path.

Hooks as alternative routing


The hookrouter module exports the useRoutes () hook, which checks the predefined route object and returns the result. In the route object, you define your routes as keys, and their values ​​as functions that will be called when the routes match. Sample code on the hooks:

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

This spelling option is more attractive. Why? Because we didn’t have to do a lot of work. With React Router, we had to render the <Route /> component for all the individual routes in our application. Not to mention all the parameters that we passed to him. With the help of hooks, we can use our routes, simply passing them to the useRoutes () hook:

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

This gives us exactly the same result that we would get using the React Router, but with a cleaner and easier implementation.

React Router Navigation


React Router includes a <Link /> component that helps us customize navigation through the application and manage interactive routing. We have an application with three pages, let's display them on the screen and go to them when you click:

 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> ); } 

We created the navigation that is needed to go from one page of the application to another. Here is a good example of how this works.



Use the navigation hooks


The hookrouter module provides a wrapper <A/> above the HTML <a/> tag. It is available as the react component and is 100% compatible with the native <a/> tag. The only difference is that it moves the navigation to the history stack instead of actually loading the new page.

 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> ); } 



Program navigation


The hookrouter module gives us access to the navigate () hook, to which we can pass a URL, and it will redirect the user to that URL. Each call to the navigate () function represents a forward navigation, as a result, users can click the back button in the browser to return to the previous URL. This happens by default.

 navigate('/user/'); 

However, if you need a different behavior, you can make a replacement in the browser history. The navigate () hook takes three parameters - navigate (url, [replace], [queryParams]), the second parameter is used to change the replacement behavior. It deletes the current history entry and replaces it with a new one. To achieve this effect, simply set its argument to true.

 navigate('/user', true); 

React Router switch


React Router uses the <Switch /> component to display the default page when certain routes do not match. It usually displays a 404 page to inform the user that the selected route is not defined in the application. To do this, we wrap all the routes inside the <Switch /> component and draw the 404 page, without defining the path to the file for it:

 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> ); } 

Thus, when switching to an undefined route, the React Router displays the NoPageFound component. In this way, we can inform users about where they are and what is happening while navigating the application.

Switch alternative on hooks


Since we define a route object that contains all our routes, and simply pass this object to useRoutes () hook, it becomes very simple to display routes by condition. If we define the NoPageFound component for rendering by default when the selected route is not defined, we will only need to transfer this file for rendering along with our result function as follows:

 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> ); } 



Compared to using the React Router component to render pages by default, this looks a bit cleaner and more readable.

React Router Redirects


A redirect occurs when we want to dynamically direct a user from one route to another. For example, during authorization, when a user successfully logs in, we would like to redirect him from the '/ login' route to the '/ dashboard' route.

With React Router, we can do this in several ways - using a history object or a <Redirect /> component. For example, if we have a login form, we can use the browser's history object to redirect the user to the '/ dashboard' route when entering the system:

 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 

Redirects with hooks


The hookrouter module provides us with a useRedirect () hook, which can take a source route and a destination route as parameters.

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

This will automatically redirect users to the '/ dashboard' route when the '/ user' path is found. For example, if we don’t want to show any users, and instead automatically redirect the user to his / dashboard, we’ll write it like this:

 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 } 



It is worth noting that the useRedirect () hook causes the replacement of the navigation history. As a result, there will be only one entry in the navigation history. This means that if a redirect occurs from '/ user' to '/ dashboard, as was the case in the last considered code fragment, the route' / user 'will not be displayed in the browsing history. We will only have the route '/ dashboard'.

Processing URL parameters in React Router


URL parameters help us display components based on their dynamic URLs. This works in the same way as with nested routes, but in this case the routes do not change, but are updated.

For example, if our application had different users, it would make sense to identify them separately with their individual routes, such as 'user / user1 /' and 'users / user2 /', etc. For this we need to use the URL parameters. In React Router, we simply pass a parameter (for example, id) starting with a colon in the path property of the <Route /> component:

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

We use hooks to process URL parameters


There are almost no differences in handling URL parameters in the hookrouter and React Router. The construction is the same (i.e., you can pass URL parameters to destination routes using a colon and a parameter name).

However, there is a difference in how the hookrouter works. It reads all URL parameters and places them in an object. This is done using the keys that you defined in the route object. Then all the named parameters will be redirected to the result function of your route as a combined object.

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

Using object restructuring, we simply take the id property from the props object and then apply it to our component. Thus, we get exactly the same result as with the React Router.

Conclusion


We looked at an alternative way of routing in React applications. React Router is a great tool, however, with the advent of hooks in React, much has changed, including how routing works. This hook based module offers a more flexible and cleaner way to handle routes in smaller projects.

In addition to the basic functionality discussed in the post, the hookrouter has a number of additional features, such as:


The hookrouter project has excellent documentation in which you can quickly find the question of interest.

The article used materials from the hookrouter documentation .
and the original article How React Hooks can replace React Router .

Hookrouter git repository

UPD: I didn’t see right away when making the article that I could choose the type of publication “Translation”, I apologize to the readers, I made a link to the original in the header and indicated the author.

Source: https://habr.com/ru/post/459434/


All Articles