React Router updates quickly, but it always feels like everything is the same. With a good grasp of history, I can work more easily. I have translated an article and hope to point out if there is any impassability.
The original
To understand react Router, you must learn history. Further, the History package provides the core functionality required by the React Router. It makes it easy for a single page application to change location based on navigation.
NPM install - save historyCopy the code
The history package exports three methods that correspond to three types of history: browser, Hash, and Memory.
import {
createBrowserHistory,
createHashHistory,
createMemoryHistory
} from 'history'
Copy the code
The React Router automatically creates the history object for us, so we don’t have to directly manipulate history ourselves. However, understanding them will let us know which one is more appropriate for our project.
What is history? (What is history?)
No matter what type of history you create, you’ll end up with an object with the same properties and methods.
Location
Location is the most important property in history, indicating the current ‘where’ of the application, and it contains many properties derived from the URL, such as PathName, search, and hash.
Also, each location object has a single key attribute that distinguishes the current location.
Finally, Location also contains a state property that provides additional data that the URL does not display, the associated parameter variable.
{ pathname: '/here', search: '? key=value', hash: '#extra-information', state: { modal: true }, key: 'abc123' }Copy the code
You first need a raw location to create the history object. The original location is different for each type of history. For example, Browser History parses the current URL.
One location to rule them all? (Only one location to regulate all functionality?)
Although we can only access one location at a time, History keeps track of every location visited. It is this ability to add a location and navigate through the entire location that makes history” history”. If history only cared about the current location, it would be called “present”.
In addition to the Location array, History also maintains an index of the current location associated with the array. All of this is defined in memory History, and the Location array and index values are controlled by browser and cannot be manipulated directly.
Navigation
Just having a location property is not enough. The navigation method is where history really gets interesting. These methods can manipulate and change the current location.
Push
The push method allows us to locate to a new location. It adds a new location to the end of the Location array. When push is called, the “future” locations(because of the locations generated after the current location using the back button) are discarded. When you click Link, you default to the history.push method.
history.push({ pathname: '/new-place' })
Copy the code
Replace
It’s similar to push, but it will replace the current location from the array, and “Future” locations will not be removed. The React router
uses replace.
For example, clicking a link from the current page to jump to a second page redirects you to a third page. If you use the push method, when you click the back button on the third page, you go back to the second page, then back to the third page, and so on. But if you use replace, the first page is returned back.
history.replace({ pathname: '/go-here-instead' })
Copy the code
Go, goBack, goForward
GoBack returns a page, effectively reducing the location index in the Locations array.
history.goBack()
Copy the code
GoForward, by contrast, jumps forward one page. ** Future Locations ** only works if ** future locations ** exists.
history.goForward()
Copy the code
Go is a combination of the two, more powerful. Negative arguments are used to move backward and positive arguments are used to move forward.
history.go(-3)
Copy the code
Listen
History uses observer mode, and external code can listen for location changes.
Each History object has a Listen method that takes a method as an argument. This method will be added to the sequence of listeners for history maintenance. Any time the location changes (whether the code controls change or the user clicks a browser button), the history object calls all the listener functions. So you can do some code when the location changes.
const youAreHere = document.getElementById('youAreHere')
history.listen(function(location) {
youAreHere.textContent = location.pathname
})
Copy the code
The React Router’s routing component listens to its history object so that it can re-render when the location changes.
Linking things together
Each history has a createHref method that takes a Location object and converts it into a URL. For example, the element does not parse the history object properly, nor does it understand what location is. So in order for HTML to navigate properly without parsing history, we need to convert it to actual URLs.
const location = {
pathname: '/one-fish',
search: '? two=fish',
hash: '#red-fish-blue-fish'
}
const url = history.createHref(location)
const link = document.createElement('a')
a.href = url
//
Copy the code
This overrides the required methods of the History API. There are more properties and methods, but this is enough to understand how History works.
With our powers combined
The three types of history are somewhat different, so we need to consider which type is more suitable for our project. The following compares different usage scenarios.
In the Browser
Browser and Hash histories are generally applied to browsers. They interact with the History and location Web apis to ensure that the current browser address bar displays the same address as the current location.
const browserHistory = createBrowserHistory()
const hashHistory = createHashHistory()
Copy the code
The biggest difference between the two histories is the way you create a location based on a URL. The browser history is created from the full URL, but the hash is created from the partial URL following the hash symbol #.
/ / the following URL
url = 'http://www.example.com/this/is/the/path?key=value#hash'
// 'browser history' creates a location object:
{
pathname: '/this/is/the/path',
search: '? key=value',
hash: '#hash'
}
// 'hash history' creates a location object:
{
pathname: 'hash',
search: ' ',
hash: ' '
}
Copy the code
Hashing things out
So why would anyone use hash history?
When you navigate to a URL, the server will theoretically have a file access to that URL. For a dynamic server, the file being accessed does not necessarily exist. The server detects the access URL and decides what HTML to return. For a static file server, however, it can only return files that already exist on disk. All they can do is provide urls that return those matching index.html files.
Given the limitations of static servers, the simplest and most crude solution is for the server being visited to have a ‘real’ location corresponding to the HTML being visited. Of course, for our application one location corresponds to one URL, so the use of history would be meaningless. To overcome this limitation, Hash History uses the hash part of the URL to set the location to read.
// If example.com uses a static server, these URLs all visit /my-site/index.html
http://www.example.com/my-site#/one
http://www.example.com/my-site#/two
// However, if you use hash history, the application URL will be different, and the hash part of the URL will produce a different URL.
{ pathname: '/one' }
{ pathname: '/two' }
Copy the code
The hash based feature, which is most useful for retrieving HTML when using a static server.
Memory: The Catch-all History
The great thing about Memeory is that it can be used anywhere js is available.
For example, you can use it in unit tests in a Node environment. This allows you to directly rely on the History object to test your code without running it in a browser. It can also be applied to mobile phones. The memory history called by the React-router-native application is based on the navigation of the React-Native application to achieve the location function. It even works in the browser (but the address bar loses the address information).
The biggest difference is that it maintains its own internal location array. You can set up raw data from the beginning of memory History, which contains the Location array and the current location index, rather than relying on browser-stored Locations like the other two.
const history = createMemoryHistory({
initialEntries: ['/'.'/next'.'/last'],
initialIndex: 0
})
Copy the code
When you implement your own History feature, you will encounter a lot of browser navigation problems. The easiest way to solve this problem isto rely on existing History. No matter what type of history is used, the ultimate goal isto better realize navigation in the application.
If there is something wrong, please point it out. If you think it is useful, give me a thumbs up
Part of life is working, and part of work is solving problems to please life, so live well, work well, love well (● world twentyconsciousness)