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:

  1. History.back(): returns to the previous page in the browser’s session History, similar to the browser’s back button

  2. History.forward(): points to the next page in the browser’s session History, similar to the forward button in the browser.

  3. History.go(): Jumps to a specified page in the browser session History.

  4. 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.

  5. 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.

  6. 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.