Routing trong react router và routing thông thường có gì khác nhau?
date
‣
slug
what-is-the-difference-between-react-router-and-conventional-routing
status
Published
tags
Javascript
ReactJS
summary
Routing trong ứng dụng web được kích hoạt khi người dùng thực hiện một hành động chuyển trang nào đó. Với routing, chúng ta có thể đảm bảo các requests gửi lên đến server để handle và response cho client.
type
Post
Introduction
Routing trong ứng dụng web được kích hoạt khi người dùng thực hiện một hành động chuyển trang nào đó. Với routing, chúng ta có thể đảm bảo các requests gửi lên đến server để handle và response cho client.
Hiện hầu hết các framework đều hỗ trợ routing cho việc phát triển các ứng dụng web. Ví dụ, trong NodeJS chúng ta có express.Router() dùng để tạo một đối tượng router để handle các requests. Tương tự như vậy, trong ReactJS sử dụng thư viện React Router cho routing.
Tuy nhiên có một câu hỏi đặt ra “Tại sao lại cần thư viện cho việc routing và nó có khác gì với routing thông thường”?
Trong bài viết này, chúng ta sẽ khám phá cách routing thông thường và các đặc tính của React Router cho việc routing.

Routing là gì?
Trong ứng dụng web, user có thể truy cập các trang khác nhau với sự hỗ trợ của các html element <a/> hoặc <button/> trong form. Khi user click một thẻ link hoặc button, có nghĩa là trang web sẽ update content và url mới.

Structure of URL
With every click on a link, the domain remains the same but the path changes. For example when a user clicks on the “Registration” button the URL changes to https://www.sampleURL.com/register and when the “Login” button is clicked the URL changes to https://www.sampleURL.com/login.
Now whenever the URL changes, it is the default behavior of the browser to issue a request to the server of the application. The server checks for the pathname in the URL and accordingly responds with a new HTML page.
The process in which the server handles client requests based on the pathname of the URL is known as conventional routing.
To understand this further, consider the following URL entered in the browser:
http://www.example.com/products
Quy trình xử lý một routing thông thường:
- Ví dụ khi truy cập http://www.example.com thì part của URL mặc định là “/”
- Khi user click page sản phẩm (path :”/products”), trình duyệt sẽ gửi một method http get request cho path “/products” trên server
- Router trên server sẽ gọi các function/method để xử lý đường path “/products” tương ứng. Nếu router phát hiện, HTTP request sẽ được gọi đến function đó.
- Xử lý xong router handler sẽ response 1 html page của trang sản phẩm (path “/products”)
- Trình duyệt sẽ load file html của server đã response về và hiển thị content cho user
- URL cũng sẽ tự động update thành http://www.example.com/products .
Đây là toàn bộ quá trình xử lý routing thông thường hoặc còn gọi là server-side routing

Example of server-side routing for viewing products page
A few points to be noted about server-side routing from the above example are:
- A server-side request is an equivalent of requesting a new web page from the server. For an application using server-side routing, every time the user clicks on a link in the page or enters a new URL in the browser, the route handlers must return a new document in response to the request.
- Server-side routing causes the whole page to refresh because the server responds with a new page.
- Since server-side routing leads to a full-page refresh, unnecessary data is being requested from the server. If only the color of a button needs to be changed as a response to a request, then components such as header or footer which haven’t been changed will have to be rendered again.
- Due to page refresh, data will be loaded at varied times, which will not serve as a good UI for users.
Therefore, it can take time for the responses to be displayed in conventional routing.
How do we combat this disadvantage so that render time is reduced and constant, and the whole page doesn't have to refresh? What can we improve in this routing process so that display of UI is seamless instead of the constant “blank” page being loaded for every refresh? This is where client-side routing or the React Router library comes into use.
Client-side routing
In client-side routing, whenever a request is made for a route, this request is not sent to the server. Instead, the Javascript loaded on the page handles the routing process.
Client-side routing is popular among “Single-Page Applications”, which is a single HTML file and the content of the HTML file is divided into “components”.
Instead of the traditional method of sending the request to the server, the Javascript loaded on the page intercepts this request and the following process takes place:
- Change in URL is detected by Javascript code of web page, and change in URL means that the state of the application has changed.
- A changed state implies that the view of the webpage must also be updated to stay in sync with the URL.
- The webpage can be updated by either displaying a new component, updating an already displayed component or by maybe sending a request to the server for data from the database and then displaying that data.
- Since only a part of the web page is updated, this means that the whole page will not be refreshed. Only a few elements inside the web page are being changed.
Therefore, client-side routing does not result in page refresh every time the URL is updated.
React Router

React Router
React router is a standard library in React for routing and provides smooth navigation among various components in the web page. React router uses client-side routing and provides APIs for manipulating history stack, matching pathname to the routes defined, and displaying the component matching to the pathname in the current URL.
Declarative routing in React
You might hear that React allows us to build applications with “declarative routing”, but what exactly is declarative routing?
React allows developers to use pathname in URL as a condition for rendering components. This means that when the URL changes, routes are initialized dynamically. Unlike static routing where routes have to be defined previously along with route handlers, React allows us to load different components conditionally without disturbing the layout of the page or loading a new page.
One important concept which governs the navigation of users on browsers is the browser history stack, and this must be discussed before discussing React router.
History Stack
The history stack is a stack of all locations that the users visit, which is maintained by the browser. The forward and backward buttons on the top left operate with the help of the history stack. Client-side routing enables developers to make changes in the browser history stack. If a user clicks on a link, simply push the new pathname onto the stack and change the URL.
Browser history can be manipulated by window.history . Functions such as :
- window.history.pushState()
- window.history.popState()
- window.history.replaceState()
are responsible for adding, replacing or going back to locations in the stack.
Go to the console by right click->inspect and type window.history . While I am editing this article, the output is as follows:

window.history output while editing Medium article

The path matches my URL
Other than window.history, there is also window.location which tells “where the user is currently”. You can try out location in your console, just like we did for window.history.
Now you might be wondering, when the window object itself can provide us with methods for client-side navigation, what is the use of routing libraries like React Router?
Why React Router?
The problem with the browser is that it does not have a method for listening to any change in URL. With the help of the window.history functions we can change the URL but then the components are not being rendered nor data requests are being sent to the backend. Only changing the URL is not sufficient, we have to write further code for detecting a change in URL and then display the component.
React Router defines the following APIs/packages which makes it simple for developers to issue changes in the history stack, update the state of the app with URL change and display correct UI:
- History object: the history object of React Router provides a way to detect URL changes. It is responsible for reporting URL change so that the appropriate route component can be loaded and displayed.
- BrowserRouter: this is a base Router that uses the HTML5 history API so that the UI which is displayed to the user is in sync with the URL. It is necessary because it adds the ability to route the components.
- Switch : <Switch> functions similar to Javascript switch statement. The pathname extracted by BrowserRouter is passed to the <Switch>. Switch renders the first Route whose path matches the URL. With the help of Switch, there is no ambiguity or confusion in which components should be displayed for which route.
- Route: this is the most important component in React router. Its function is to display a particular UI when the current URL matches its path.
- Link: <Link> is responsible for declarative routing which React router provides. When the user clicks on <Link>(<Link> displays as <a> tag in UI), the default request for server to render a new HTML page is prevented. <Link> causes only the URL to change. The history object listens for URL change and passes it to the base Router for further routing.
Now below is an example of a React app to demonstrate routing using the anchor element(<a>) for conventional routing and <Link> for React routing.
<a> tag in React (page refresh)
Consider the following code for a React application with the following directory structure:

In this app, we have the following components:
- Cart component in Cart.jsx, this contains a link for products component.
- Products component in Products.jsx, this contains a link for cart component.
- Both these components are imported in App.jsx.
- Do not forget to install “react-router-dom”. We will be using APIs of this library for routing.
Following is the code for 3 files:
//App.jsx
import React from “react”;
import { BrowserRouter, Route, Switch } from “react-router-dom”;
import { Products } from “./Products.jsx”;
import { Cart } from “./Cart.jsx”;
export const App = () => {
return (
<div className=”App”>
<h1>Testing routing without react router</h1>
<BrowserRouter>
<Switch>
<Route path=”/products”>
<Products />
</Route>
<Route path=”/cart”>
<Cart />
</Route>
</Switch>
</BrowserRouter>
</div>
);
};Products.jsx code:
//Products.jsx
import React from “react”;export const Products = () => {
return (
<div>
<h1>Products</h1>
<a href=”/cart”>Cart</a>
</div>
);
};Cart.jsx code:
//Cart.jsx
import React from “react”;export const Cart = () => {
return (
<div>
<h1>Cart</h1>
<a href=”/products”>Products</a>
</div>
);
};When we view the output in the browser, open the Network tab by right click -> Inspect option. Now notice whenever you are clicking on the “Product” or “Cart” link the following happens:
- Page refreshes.
- A new request is sent every time to the server running on your terminal and the entire HTML page is loaded. You can observe this in the Network section towards the right in the below output

Continuously the page refreshes every time the URL changes.
Why is this happening?? This is due to the behavior of the anchor element (<a>) which we are using to route the components. To fully take advantage of React Router, we must use <Link> instead of <a> as this only causes URL change which is detected by the history object.
Using <Link> in React router
We will simply replace the anchor elements in Product.jsx and Cart.jsx with the <Link> component and again view the output in the browser.

Cart.jsx code change: replace <a> with <Link>

Product.jsx code change : replace <a> with <Link>

Notice there is no page refresh and re-loading of the entire HTML page with <Link>
And voila! As you can observe, without a page refresh, you can switch between products and cart.
This not only enhances user experience but also improves the application performance by giving users the feel that “multiple” web pages are being displayed, when in fact it is only a single page with various components.
The process of routing with React router when user clicks in “Products” link is:
- The URL updates to http://www.example.com/products. This change in URL is detected by the history object of React router.
- The history object informs BrowserRouter of the change in URL. BrowserRouter extracts the pathname “/products” and passes it to Switch of React router.
- The pathname “/products” is tested against the “path” prop of different “Routes” defined in Switch.
- <Switch> returns the “Route” which has path as “/products” and the component associated with this Route is loaded on the index.html file.
- Therefore, without the browser sending any request to the server, the products page was displayed without a refresh.

React Router working, instead of updating URL after loading content(like in server-side routing), the URL updates first, and based on the URL, the component is loaded.
Conclusion
Hopefully, you were able to understand how React Router works differently than conventional routing. Server-side routing and client-side routing have got their pros and cons, and according to the goal of your project, you can decide which method to use for routing!
