Client-Side Routing in React
Tags: react
Published: 2021-11-23 02:56:33

####Introduction

On this blog post, I would like to share a general overview of the concept of client-side routing that I have learned through the React phase. It was very helpful to use React tools in one project to understand the hierarchy of the components as well as nested children.

####Definition

Client-side routing comes into place when building a single-page-application to separate its components onto different pages based on the endpoint of the URL of each page. The client-side routing is the internal handling of a route inside the Javascript file that is rendered to the client; without making additional Get requests for new HTML documents other than the initial and only Get request. 

####Pro

The major benefit of client-side routing is speed. Since the client-side code is responsible for routing, fetching, and displaying data in the browser, the client side router swaps the components in response to the user clicks. 

####Limitations

The limitations of client-side routing consist of:

- It takes a while to load all the CSS and Javascript on the initial GET especially if the application size is large.
- It is hard to track page views via analytic tools. 
- Single-page applications are complicated design wise compare to multi-page applications.

####React Router 

React Router is the client-side library that enables two major features:

- Conditional rendering of components based on the endpoint of the URL.
- Programmatic navigation that updates the content of the page without making new GET requests.

##React Router Code for Main Routes


The first step to start using React Router is to install react-router-dom in the terminal: <$npm install react-router-dom>.Then, import Browser Router from react-router-dom in index.js file:

![import Browser Router from react-router-dom in index.js file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdq3reyjuwlktjho8gas.png)

Next, import Route from react-router-dom in the parent component "App":

![import Route from react-router-dom in the parent component "App"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oyf3348ruj0vs3ljltqu.png)

We use a Switch component to give the routes more predictive behavior. The Switch component is also imported from react-router-dom:

![import Switch from react-router-dom](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1r32h7ds2r0ecurvkgn.png)

![wrap Routes with Switch components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4beuz9vjgx2l1u1zef29.png)

Now that we define our routes, we can manipulate them via the address bar; but there are more efficient ways to achieve that via other tools such as Link and NavLink provided by the React Library.

####NavLink

The NavLink renders an anchor tag < a > to the dom and is used as a navigation bar with built in and customizable styling. NavLink should be placed outside and above the switch component so it can be accessed and displayed in all the pages. An example of NavLink component:

![NavLink Navbar example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/39g0emuh3um5l2a1n44r.png)

####Link

Similarly to NavLink, Link also renders an anchor tag < a > to the dom. Link can be used within the application pages as buttons with links that takes you to specific routes. Example of Links:

![Example of Links with specific routes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggokgcb75n97y24ar7cs.png)

Note that routes are following RESTful conventions. 

##React Code for Nested Routes

####useParams Hook

React modular applications are perfect tool for displaying lists of items. Going back to the example of list of cars (see code snippets above), the user should be able to click a car card and be directed to car details. Since, we are fetching the data using a db-json server and each car in the list has its own unique id, we can use useParams() method to get dynamic params from the URLs and therefore display the correct item.
First, we have to import useParams() method from react-router-dom. 

![import useParams from react-router-dom](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knvscqyezqhmx7g8zkfe.png)

Next, we have to assign the useParams() method to a variable inside our ItemDetails (i.e. CarDetails) component.

![assign useParams to a variable](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8xbtv5qpfjjng6zw4hf.png)

The id variable can be used then to fetch that specific item:

![fetch specific id using useParams variable](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ya7yg9fqdhfqn08fggas.png)

##Programmatic Navigation

The purpose of programmatic navigation is to direct the user to different pages without the need to click on a link. For instance, when the user submit a form (a new item) and need to be directed to the list of items to see the newly created item displayed in the original list. Another example is when we perform a delete action and we need to direct the user back to the main list. One way to achieve that is via useHistory Hook. 

####useHisory Hook 

Fisrt, we import the useHistory Hook from react-router-dom.

![import useHistory hook from react-router-dom](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qf5p5w06qg2peukwgnbz.png)

Then, assign it to a variable:

![assign a variable to useHisory hook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gp92gzn3j7ql20fvvqbp.png)

Here is an example of Patch request of a form submit action where the user is directed to the main list after submitting the new item:

![patch request with useHisory hook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/etfv2z6f94qk0lgkvhx7.png)

Here is another example of Delete request where the user will be directed to the main list of cars after deleting the a specific item (car):

![delete request with useHistory hook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqjojaz2b4qzvk8r6skg.png)

##Conclusion

This was a general overview of the concept of client-side routing with some useful hooks from the react router library.