Starting with the React-Router, the system learns the front-end routing solution

React-router is a routing solution in the React scenario. This section will learn the implementation mechanism of React-Router and explore common front-end routing solutions based on it.

[Note] : For those who have not used the React-Router, click here to get started quickly.

1. Learn about the React-router

In keeping with the principle of getting to the topic as quickly as possible, here is a simple Demo to help you quickly understand the core features of the React-Router. Take a look at the following code (explained in the comments) :

import React from "react"; Import {BrowserRouter as Router, Route, Link} from "react-router-dom"; // Export the target component const BasicExample = () => (// The component is wrapped with Router <Router> <div> <ul> <li> // the specific tag is wrapped with Link <Link To ="/">Home</Link> </li> <li> // Specific tags wrap with Link <Link to="/about"> about </Link> </li> <li> // Specific tags wrap with Link <Link To ="/dashboard">Dashboard</Link> </li> </ul> <hr /> // Route <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/dashboard" component={Dashboard} /> </div> </Router> ); / / Home components define const Home = () = > (< div > < h2 > Home < / h2 > < / div >). // About component definition const About = () => (<div> <h2>About</h2> </div>); // define Dashboard const Dashboard = () => (<div> <h2>Dashboard</h2> </div>); export default BasicExample;Copy the code

The Demo renders the page as shown below:

When different links are clicked, different component content is displayed inside the UL element. For example, clicking on the “About” link will display the contents of the About component, as shown below:

Notice that after clicking About, the interface changes in two places (see the red icon below). In addition to the content of the UL element, the routing information is also changed.

React-router has a lot of function points, but as the front-end routing solution of the React framework, it has the most basic and core capability — route jump. And that’s the focus of the rest of the discussion.

React-router is a Router that can jump to a Router.

React-router is a Router that redirects routes.

First, review the first line of code in the Demo:

import { BrowserRouter as Router, Route, Link } from "react-router-dom";
Copy the code

This line of code is to implement a simple route jump effect. It introduces the following three components from the React-Router:

  • BrowserRouter

  • Route

  • Link

These three components represent the three core roles of the React-Router:

  • Routers, such as BrowserRouter and HashRouter

  • Routes, such as Route and Switch

  • Navigation, such as Link, NavLink, Redirect

Routing (represented by Route) is responsible for defining mappings between paths and components, while navigation (represented by Link) is responsible for triggering path changes, and routers (including BrowserRouter and HashRouter) will follow the mappings defined by Route. Matches its corresponding logic for the new path.

This is how the three characters “play together”. The most notable of these is the Role of the Router, which is officially described in the React Router documentation as “the core of the React Router application.” Learn React Router, the most important thing is to understand how the Router works.

3. Routers: BrowserRouter and HashRouter

The router is responsible for sensing the change of route and responding to it. It is the most important part of the whole routing system. The React-Router allows us to use both hash (for HashRouter) and Browser (for BrowserRouter) routing rules. Both rules are described here.

HashRouter, BrowserRouter, HashRouter, HashRouter, BrowserRouter That’s true. Let’s look at the source code for HashRouter:

Take another look at BrowserRouter’s source code:

You can see that the two files are remarkably similar, and the key difference is highlighted in the diagram, namely that they call different history instantiation methods: HashRouter calls createHashHistory, BrowserRouter calls createBrowserHistory.

Both instantiation methods of History are derived from a separate code base called History, so there’s no need to get bogged down in implementation details here. For the createHashHistory and createBrowserHistory apis, the focus is on understanding the characteristics of each.

  • CreateBrowserHistory: It will use the HTML5 History API in the browser to handle urls (see the illustration in red below). It can handle urls like this, example.com/some/path. As a result, BrowserRouter uses HTML 5’s History API to control route jumps.

  • CreateHashHistory: This is a method that uses hash tag (#) to handle urls like this, example.com/#/some/path. It can be seen that the definition of various methods in its source code basically revolves around hash (as shown in the figure below), from which it can be seen that HashRouter controls route jumps through the hash attribute of URL.

[Note] : We will continue to discuss hash and history patterns in the following sections.

Now, having seen the surface, we understand the mechanism behind it. Let’s go back to where we started and ask ourselves one more question: Why do we need a React-Router?

Or to push the question a little further: Why do we need front-end routing?

It all started a long time ago.

4. Understand front-end routing — what is it? Solve what problem?

1) Background — the emergence of the problem

In the early days of front-end technology, each URL was A page, and if you wanted to switch from page A to page B, you had to refresh the page. It wasn’t a great experience, but it was initially a necessity — after all, users could only request data again if they refreshed the page.

Then something changed — Ajax came along that allowed people to make requests without refreshing the page; Co-existing with this is the need to update the content of a page without refreshing it. In this context, SPA (single page application) emerged.

SPA greatly improves the user experience by allowing the page to update its content without refreshing it, making it smoother to switch between content. But in the early days of SPA, people didn’t think about “positioning” — the URL of the page was the same before and after the content switch, which caused two problems:

  • SPA don’t really know the current page “progress to which step”, could you under a site after repeated “forward” finally calls out a piece of content, but at this time, just refresh the page, all will be reset, you must repeat before operation can to locate the content – SPA won’t “remember” your operation;

  • Having only one URL to map a page is not SEO friendly either, as search engines cannot gather comprehensive information.

To solve this problem, front-end routing emerged.

2) Front-end routing — SPA “location” solution

Front-end routing helps us “remember” where the user is currently on a single page — matching each view in the SPA with a unique identity. This means that new content triggered by a user’s advance or retreat is mapped to a different URL. Even if he refreshes the page, the content will not be lost because the current URL identifies where he is.

So how do you do that? The following two problems should be solved first.

  • When the user refreshes the page, the browser by default relocates the resource (sends the request) based on the current URL. This action is not necessary for a SPA, because a SPA, as a single page, will have only one resource corresponding to it anyway. In this case, if the normal request-refresh process is followed, the user’s forward and backward operations cannot be recorded.

  • A single page application is a URL and a set of resources for the server. So how to use “different URLS” to map different view contents?

From these two issues, there is no way the server can save the SPA scenario. So it’s up to the front end to take care of itself, otherwise what’s called “front end routing”? As a front end, the following solutions can be provided.

  • Intercept the user’s refresh operation to prevent the server from blindly responding and returning the resource content that does not meet the expectation, and completely digest the refresh action in the front-end logic.

  • Aware of URL changes. We’re not going to reinvent urls or create N urls out of thin air; Instead, the URL is still the original URL, but some minor processing to it, these processing does not affect the nature of the URL itself, does not affect the server’s recognition of it, only the front end can perceive. Once this is sensed, the front end uses JS to generate different content for it based on these changes.

3) Practical ideas — Hash and history

Then comes the key point: what are the current implementations of front-end routing in the front-end world? The two practices to learn here are Hash and history.

(1) Hash mode

Hash mode is an implementation of changing the # delimited string at the end of the URL (which is essentially the hash value on the URL) to make the page aware of the routing change. For example, a URL like this:

https://www.imooc.com/
Copy the code

The URL can be made slightly different by adding and changing the hash value:

// Home page https://www.imooc.com/#index // Active page https://www.imooc.com/#activePageCopy the code

This “difference” is completely perceptible to the front end — JS can help us capture the contents of the hash. The roadmap for implementing routing in hash mode is as follows:

  • The hash value of the current URL can be changed directly via the location exposed property:
window.location.hash = 'index';
Copy the code
  • (2) Hash awareness: By listening for the “hashchange” event, you can use JS to catch changes in the hash value, and then determine whether the page content needs to be updated:
Window. addEventListener('hashchange', function(event){// Update content based on hash changes},false)Copy the code

(2) History mode

As you know, in the upper left corner of the browser, there is usually an action point like this:

By clicking the forward and back arrows, you can jump from page to page. This behavior, in fact, can be implemented through the API.

The browser’s History API gives us the ability, in HTML 4, to manipulate the history and jump through the following interface:

Back () // Back to the previous page window.history.go(2) // Forward two pages window.history.go(-2) // The back page or twoCopy the code

Isn’t that interesting? Unfortunately, at this stage, you can only “switch” pages, not “change” them. However, starting with HTML 5, browsers support pushState and replaceState apis, which allow you to modify and add to browsing history:

history.pushState(data[,title][,url]); ReplaceState (data[,title][,url]); // Add a record history.replaceState(data[,title][,url]); // Modify (replace) the current page in the browsing historyCopy the code

So that you can modify the action, then you need to have the ability to sense the modification. In history mode, you can listen for popState events to be aware of changes:

window.addEventListener('popstate', function(e) {
  console.log(e)
});
Copy the code

The PopState event is emitted whenever the browsing history changes.

[Note] Calls to methods like go, Forward, and back do trigger popState, but pushState and replaceState do not. However, we can manually trigger events through custom events and the global event bus.

5, summary

This lecture is based on the react-Router as the breakthrough point, combined with the source code to analyze the implementation principle of the “jump” in the React-Router, thus leading to the “front-end routing scheme” this knowledge point relative to the system discussion. So far, everyone has a deep memory of the heavy and difficult knowledge involved in the ecology around React.

The next lecture will focus on React design patterns and best practices and React Performance optimization. At that time, after understanding React from the perspective of “production practice”, I believe my understanding of React will be improved to a new level.

Learning the source (the article reprinted from) : kaiwu.lagou.com/course/cour…