This article introduces to you a detailed analysis of the core history library in React Router. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Preface
Use React to develop slightly more complex applications. React Router is almost the only choice for routing management. Although React Router has undergone four major version updates and its functions have become more and more abundant, no matter how it changes, its core dependence on the history library has not changed. Let's take a look at what functions this library with 4k stars on github provides.
HTML5 history object
Talking about the history library, do you think this word is a bit familiar? Yes, a new history object with the same name has also been added to the HTML5 specification. Let's take a look at what problems this history object is used to solve.
In the era when jQuery dominated the front-end, updating pages through ajax requests without refreshing was a very popular page processing method at that time. The prototype of SPA evolved at that time. In order to mark changes to the page so that the correct page elements can still be displayed after refreshing, the hash value of the URL is generally changed to uniquely locate the page. But this brings up another problem: users cannot use forward/backward to switch pages.
In order to solve this problem, the history object came into being. When the URL or hash of the page changes, the browser will automatically push the new URL into the history object. A state array is maintained inside the history object to record changes in the URL. When the browser performs a forward/backward operation, it actually calls the corresponding method of the history object (forward
/back
) to retrieve the corresponding state to switch pages.
In addition to operating the URL, the history object also provides two methods that can update the internal state without operating the URL, namely pushState
and replaceState
. You can also store additional data in the state, and then retrieve it through event.state
in the onpopstate
event. If you want a deeper understanding of the history object, you can refer to here, and here.
The relationship between the history library and the HTML5 history object
Let’s go back and look at the history library. It essentially does the following 4 things:
Learns from the concept of HTML5 history object, and extends some functions based on it
Provides 3 types of history: browserHistory, hashHistory, memoryHistory, and maintains a unified API
Supports the publish/subscribe function. When the history changes, the subscription function can be automatically triggered
Provides practical functions such as jump interception, jump confirmation and basename
Let’s compare some similarities and differences between the two APIs. The following is the history library:
const history = { length, // 属性,history中记录的state的数量 action, // 属性,当前导航的action类型 location, // 属性,location对象,封装了pathname、search和hash等属性 push, // 方法,导航到新的路由,并记录在history中 replace, // 方法,替换掉当前记录在history中的路由信息 go, // 方法,前进或后退n个记录 goBack, // 方法,后退 goForward, // 方法,前进 canGo, // 方法,是否能前进或后退n个记录 block, // 方法,跳转前让用户确定是否要跳转 listen // 方法,订阅history变更事件 };
The following is the HTML5 history object:
const history = { length, // 属性,history中记录的state的数量 state, // 属性,pushState和replaceState时传入的对象 back, // 方法,后退 forward, // 方法,前进 go, // 方法,前进或后退n个记录 pushState, // 方法,导航到新的路由,并记录在history中 replaceState // 方法,替换掉当前记录在history中的路由信息 } // 订阅history变更事件 window.onpopstate = function (event) { ... }
It can be seen from the comparison that the relationship between the two is very close. The history library can be said to be the history object. A superset of , which is a more powerful history object.
createHashHistory source code analysis
Below, we take one of the three history types, hashHistory, as an example to analyze the history source code and see what it does. Let’s first look at how it handles hash changes.
// 构造hashHistory对象 const createHashHistory = (props = {}) => { ... const globalHistory = window.history; // 引用HTML5 history对象 ... // transitionManager负责控制是否进行跳转,以及跳转后要通知到的订阅者,后面会详细讨论 const transitionManager = createTransitionManager(); ... // 注册history变更回调的订阅者 const listen = listener => { const unlisten = transitionManager.appendListener(listener); checkDOMListeners(1); return () => { checkDOMListeners(-1); unlisten(); }; }; // 监听hashchange事件 const checkDOMListeners = delta => { listenerCount += delta; if (listenerCount === 1) { window.addEventListener(HashChangeEvent, handleHashChange); } else if (listenerCount === 0) { window.removeEventListener(HashChangeEvent, handleHashChange); } }; // hashchange事件回调 const handleHashChange = () => { ... // 构造内部使用的location对象,包含pathname、search和hash等属性 const location = getDOMLocation(); ... handlePop(location); }; // 处理hash变更逻辑 const handlePop = location => { ... const action = "POP"; // 给用户展示确认跳转的信息(如果有的话),确认后通知订阅者。如果用户取消跳转,则回退到之前状态 transitionManager.confirmTransitionTo(location, action, getUserConfirmation, ok => { if (ok) { setState({action, location}); // 确认后通知订阅者 } else { revertPop(location); // 取消则回退到之前状态 } }); }; // 更新action,location和length属性,并通知订阅者 const setState = nextState => { Object.assign(history, nextState); history.length = globalHistory.length; transitionManager.notifyListeners(history.location, history.action); }; ... }
The above is the logic for handling passive hash changes. In one sentence, it can be summarized as follows: subscribe to the hash change event, determine whether the change is really needed, update your own attributes if a change is needed, and notify the subscriber. If no change is needed, Go back to the previous state.
Let’s take a look at what the transitionManager does, focusing on the content related to publishing/subscribing, and ignoring the content related to the user confirmation jump.
const createTransitionManager = () => { ... // 内部维护的订阅者列表 let listeners = []; // 注册订阅者 const appendListener = fn => { let isActive = true; const listener = (...args) => { if (isActive) fn(...args); }; listeners.push(listener); return () => { isActive = false; listeners = listeners.filter(item => item !== listener); }; }; //通知订阅者 const notifyListeners = (...args) => { listeners.forEach(listener => listener(...args)); }; ... }
The code here is clear at a glance, it is to maintain a list of subscribers and notify the relevant functions when the hash changes.
The above is the content related to passive update when hash changes. Let's take a look at the code related to active update. Taking push
as an example, replace
is similar.
const push = (path, state) => { ... const action = "PUSH"; const location = createLocation(path, undefined, undefined, history.location); transitionManager.confirmTransitionTo(location, action, getUserConfirmation, ok => { if (!ok) // 如果取消,则不跳转 return; ... pushHashPath(encodedPath); // 用新的hash替换到url当中 ... setState({action, location}); // 更新action,location和length属性,并通知订阅者 }); }; // 用新的hash替换到url当中 const pushHashPath = path => (window.location.hash = path);
When the browser performs forward and backward operations, the history library is actually implemented by operating the HTML5 history object.
const globalHistory = window.history; const go = n => { ... globalHistory.go(n); }; const goBack = () => go(-1); const goForward = () => go(1);
When window.history.go
is called, the hash will change, triggering the hashchange event, and then the history library will notify the relevant subscribers of the change.
Summary
This article provides a more in-depth introduction to the history library that React Router core relies on. Starting from the new history object in HTML5, we compare its inextricable relationship with the history library, and use hashHistory as an example to analyze the implementation details of its code in detail.
Finally, let’s review what the history library has done:
-
Learn from the concept of HTML5 history object and expand some functions on its basis
Provides 3 types of history: browserHistory, hashHistory, memoryHistory, and maintains a unified API
- ##Supports publish/subscribe function, when the history changes At this time, the subscription function can be automatically triggered
- Provides practical functions such as jump interception, jump confirmation and basename
Related recommendations:
How to use h5 to implement react drag and drop sorting components (with code)
How to solve the collapse problem of margin-top in HTML5 (Code attached)
What are the tags and common rules in HTML5? Introduction to html5 tags and rules
The above is the detailed content of Detailed analysis of the core history library in React Router. For more information, please follow other related articles on the PHP Chinese website!

H5 brings a number of new functions and capabilities, greatly improving the interactivity and development efficiency of web pages. 1. Semantic tags such as enhance SEO. 2. Multimedia support simplifies audio and video playback through and tags. 3. Canvas drawing provides dynamic graphics drawing tools. 4. Local storage simplifies data storage through localStorage and sessionStorage. 5. The geolocation API facilitates the development of location-based services.

HTML5 brings five key improvements: 1. Semantic tags improve code clarity and SEO effects; 2. Multimedia support simplifies video and audio embedding; 3. Form enhancement simplifies verification; 4. Offline and local storage improves user experience; 5. Canvas and graphics functions enhance the visualization of web pages.

The core features of HTML5 include semantic tags, multimedia support, offline storage and local storage, and form enhancement. 1. Semantic tags such as, etc. to improve code readability and SEO effect. 2. Simplify multimedia embedding with labels. 3. Offline storage and local storage such as ApplicationCache and LocalStorage support network-free operation and data storage. 4. Form enhancement introduces new input types and verification properties to simplify processing and verification.

H5 provides a variety of new features and functions, greatly enhancing the capabilities of front-end development. 1. Multimedia support: embed media through and elements, no plug-ins are required. 2. Canvas: Use elements to dynamically render 2D graphics and animations. 3. Local storage: implement persistent data storage through localStorage and sessionStorage to improve user experience.

H5 and HTML5 are different concepts: HTML5 is a version of HTML, containing new elements and APIs; H5 is a mobile application development framework based on HTML5. HTML5 parses and renders code through the browser, while H5 applications need to run containers and interact with native code through JavaScript.

Key elements of HTML5 include,,,,,, etc., which are used to build modern web pages. 1. Define the head content, 2. Used to navigate the link, 3. Represent the content of independent articles, 4. Organize the page content, 5. Display the sidebar content, 6. Define the footer, these elements enhance the structure and functionality of the web page.

There is no difference between HTML5 and H5, which is the abbreviation of HTML5. 1.HTML5 is the fifth version of HTML, which enhances the multimedia and interactive functions of web pages. 2.H5 is often used to refer to HTML5-based mobile web pages or applications, and is suitable for various mobile devices.

HTML5 is the latest version of the Hypertext Markup Language, standardized by W3C. HTML5 introduces new semantic tags, multimedia support and form enhancements, improving web structure, user experience and SEO effects. HTML5 introduces new semantic tags, such as, ,, etc., to make the web page structure clearer and the SEO effect better. HTML5 supports multimedia elements and no third-party plug-ins are required, improving user experience and loading speed. HTML5 enhances form functions and introduces new input types such as, etc., which improves user experience and form verification efficiency.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Dreamweaver Mac version
Visual web development tools

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function
