directory

  • The react – the router is introduced
  • React-router Redirects routes
    • Common Routing Modes
    • Simulate the react-router route redirect
  • conclusion

The react – the router is introduced

Declarative routing for React

React-router github

React -router declares routes for React

Components are the heart of React’s powerful, declarative programming model. React Router is a collection of navigational components that compose declaratively with your application. Whether you want to have bookmarkable URLs for your web app or a composable way to navigate in React Native, React Router works wherever React is rendering–so take your pick!

This document is from the react-router official documentation

Components are at the heart of react’s powerful declarative programming model. React Router is a set of navigation components that are declaratively combined with your application. Whether you want to add bookmarkable urls to your Web apps, or add a composable navigation to React Native, the React Router works where React renders are, so you can choose!

In short, react-Router provides routing capabilities for React. Both Web and React Native applications can use react-Router for route management.

Here only forwebThe application of the routing principle is analyzed

React-router Redirects routes

Common Routing Modes

SPA(single page application) routing modes are generally divided into two types:

  1. hashmodel
  2. historymodel

React-router redirects routes

In react applications with react-router introduced, we usually use Link components provided by react-router-dom to redirect routes. In the Link component, the code related to route hop is as follows:

const method = replace ? history.replace : history.push;

method(location);
Copy the code

Replace indicates whether to replace the current route, and location indicates the route to be replaced

React-router uses history.replace and history.push to redirect routes. Encapsulation of the window. The history, use of the window. The history. PushState and window history. ReplaceState two apis, achieve url jump without reloading the page;

Simulate the react-router route redirect

Create-react-router (react^16.13.1) {🌰} create-react-router (react^16.13.1) {🌰}

History.ts


interface Listener {
  (url: string) :void
};

interface History {
  listeners: Array<Listener>,
  push: {
    (url: string, state? : {[propsName:string] :any} | null) :void
  },
  listen: {
    (fn: Listener): {(): void}}};const createHistory = (): History= > {
  const globalHistory = window.history;
  const _history: History = {
    listeners: [].listen(fn) {
      this.listeners.push(fn);
      return () = > {
        let i: number = -1;
        this.listeners.find((listener, index) = > {
          if (listener === fn) {
            i = index;
          }
          return listener === fn;
        });
        if(i ! = = -1) {
          this.listeners.splice(i, 1); }}; },push(url, state) {
      globalHistory.pushState(state, ' ', url);
      this.listeners.forEach(listener= >{ listener(url); }); }};return _history;
};

export default createHistory;
Copy the code

The above is a simple implementation of the history library, which only realizes the function of push (but does not realize the replace function), mainly divided into three parts:

  1. listeners: Array type, whenhistory.pushWhen called, execute in sequencelistenersFunction in;
  2. listen: Function type that accepts a functionlistenerMake parameters, and willlistener Added to thelisteners, waiting forhistory.pushImplementation; Return a functionunlisten, will execute when the currentlistenerfromlistenersRemove;
  3. push: Function type, accept oneurlAs an argument, executeglobalHistory.pushState(hereglobalHistoryforwindow.history), and in turnlistenersAll functions in;

As you can see from the code above, History mainly uses the idea of a subscription-publish design pattern;

App.ts

import React, {useEffect, useState} from 'react'; import createHistory from './history'; const history = createHistory(); const Page1: React.FC = props => { return <div>Page1</div>; }; const Page2: React.FC = props => { return <div>Page2</div>; }; const App: React.FC = props => { const [location, setLocation] = useState<string>(window.location.pathname); const pushHistory = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>, url: string): void => { event.preventDefault(); history.push(url); }; const renderComponent = (): ReactElement => { switch (location) { case '/page1': { return <Page1></Page1>; } case '/page2': { return <Page2></Page2>; } default: { return <Page1></Page1>; }}}; UseEffect () => {// after rendering the page for the first time, execute history.listen((url) => {setLocation(url); }); } []); return ( <div> <div className="nav"> <a href="/page1" onClick={(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => pushHistory(event, '/page1')}>page1</a> <a href="/page2" onClick={(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => pushHistory(event, '/page2')}>page2</a> </div> <div>{renderComponent()}</div> </div> ); }; export default App;Copy the code

The page structure generated by the above code is divided into:

  • Navigation part: to prevent the default events of hyperlinks, avoid refreshing the page, and bind new click events, triggerhistory.pushRoute jump;
  • Route component rendering part: PasslocationVariable renders the corresponding routing component;

The logical structure of the code is as follows:

  1. To create ahistoryThe sample;
  2. performrenderComponentFunction to render the component corresponding to the current route;
  3. AppUsed when the first rendering is completehistory.listenRegisters a listening event to be used when the event is calledsetLocationwilllocationSet tourlParameters; And will behistory.listenThe returned function is assigned to the variableunlisten;
  4. Click the hyperlink and executehistory.pushTo redirect a route, runhistory.listenTo execute the callback function insetLocationModify thelocationThe value of the variable causes the component to re-render,renderComponentThe function is re-executed and the routing component is successfully rendered;
  5. When exiting the page, executeunlistenFunction to destroy the current listening event;

conclusion

This article mainly analyzes the route jump principle in react- Router, and implements a simple history library by itself. Of course, the logic of the history library is more complicated, so we will not go into the details here. If you like, please give a thumbs up. The next article will continue with the source code analysis of the React-Router component. If you find any errors in this article, please leave a comment in the comments section.