The principle of
Currently, there are two common routes, HashRouter and BrowserRouter
HashRouter
Hash routing mainly changes the URL by changing the hash value. Since it only changes the hash value, it does not trigger a page refresh. It is good for applying local updates to a single page
Window.addeventlistener ('hashchange', function(e) {console.log('hashchange', e) // update page})Copy the code
BrowserRouter
History is a new API for H5 that allows you to change urls without refreshing the page. The main apis are:
-
History.back(): returns to the previous page in the browser’s session History, similar to the browser’s back button
-
History.forward(): points to the next page in the browser’s session History, similar to the forward button in the browser.
-
History.go(): Jumps to a specified page in the browser session History.
-
History.pushstate ():pushState pushes the given data onto the browser session History stack. This method takes three parameters, the object, the title, and a list of urls. PushState changes the current page URL, but is not accompanied by a refresh.
-
History.replacestate ():replaceState replaces the url of the current session page with the specified data. ReplaceState also changes the URL of the current page, but does not refresh the page.
-
The above is just to change the URL without refreshing the page, we also need to listen for the user to change back and forth. Popstate is a listening event for History that listens for changes in history
Okay, so that’s basically how it works
implementation
The react Context API is used to store routing information, and the subcomponents are used to render the routing information according to the context value. The code is implemented by hook
BrowserRouter
import React, { useState, useEffect } from "react"; // createContext export const RouterContext = react.createcontext (window.location.pathname); export default function({ children }) { const [url, setUrl] = useState(window.location.pathname); useEffect(() => { function popstate(e) { set(window.location.pathname); } window.addEventListener("popstate", popstate); return () => window.removeEventListener("popstate", popstate); }, []) const router = { history: { push: function(url, state, title) { window.history.pushState(state, title, url); setUrl(url); }, replace: function(url, state, title) { window.history.replaceState(state, title, url); setUrl(url); Go: window.history. Go, goBack: window.history. Back, goForward: window.history. window.history.length }, url: url }; return ( <RouterContext.Provider value={router}>{children}</RouterContext.Provider> ); }Copy the code
Route
import React, { useContext } from "react"; import { RouterContext } from "./BrowserRouter"; Function Route({Component, path}) {// Get context const {history, url} = useContext(RouterContext); const match = { path, url }; const Component = component; return url === path && <Component history={history} match={match} />; } export default Route;Copy the code
Link
import React, { useContext } from "react";
import { RouterContext } from "./BrowserRouter";
import styled from "styled-components";
const A = styled.a`
text-decoration: none;
padding: 5px;
`;
function Link({ children, to }) {
const { history } = useContext(RouterContext);
const onClick = e => {
e.preventDefault();
history.push(to);
};
return (
<A href={to} onClick={onClick}>
{children}
</A>
);
}
export default Link;
Copy the code
conclusion
See Github source code is actually a simple thing, understand the principle is easy to implement, read this article, you can also try to implement a HashRouter.