React Router study notes

routing

Routing is originally a back-end concept, originating from the server, where routing describes the mapping between urls and handlers. Different resources are requested through different routes.

The back-end routing

When you switch different urls in the browser address bar, you need to send a request to the background server each time. The server responds to the request and sends the corresponding resources to the browser, and the browser page will refresh.

For example, if you deploy an Apache Web server, you can access HTML, JS, CSS and other files from the server. Or you can develop some backend server in PHP, Java, or Node.js that will return the HTML file you want when you access the URL.

Back-end routing can take some of the pressure off the front end, because the HTML file splicing, data splicing is done by the server. However, when the network speed is relatively slow, the page loading delay will increase, and the user experience is not good.

The front-end routing

The essence of front-end routing is some explicit or implicit manipulation of the DOM, and different page components are displayed when different paths are accessed. With the rise of Single Page Application (SPA), front-end routing is becoming more and more popular. In Single Page Application, not only the data interaction between pages is not refreshed, but also the Page jump is not refreshed, which greatly saves the performance overhead brought by frequent requests for background data. Front-end routing is not just a page switch, but a way of organizing code.

Principle of front-end routing

Simply speaking, the browser API is used to detect URL changes, intercept URL address, and then parse, match to the corresponding page components, rendering the DOM.

There are two front-end routing modes: Hash mode and History mode.

Hash pattern

The hash is not a hash, but the “#”, also known as the anchor point, is used to position the page itself. The change in value after # triggers the onhSahChange event, which displays the different pages by changing the hash value (the load event is executed on the first load).

Implement a simple hash route

import React from 'react'
import ReactDOM from 'react-dom'

class HashRouter {
  constructor(routes) {
    // The current URL
    this.currentUrl = ' '
    this.routes = routes
    this._refresh = this._refresh.bind(this)
    // Execute the load on the first load
    window.addEventListener('load'.this._refresh, false)
    // Triggered when the hash route changes
    window.addEventListener('hashchange'.this._refresh, false)}// Get the hash path and return/if none is found
  _getHashPath(url) {
    const index = url.indexOf(The '#')
    if (index >= 0) {
      return url.slice(index + 1)}return '/'
  }

  _refresh(event) {
    let curURL = ' '
    if (event.newURL) {
      // Hash route change, triggered by the HashChange event
      curURL = this._getHashPath(event.newURL || ' ')}else {
      // This is triggered by the load event
      curURL = this._getHashPath(window.location.hash)
    }
    this.currentUrl = curURL

    let route = null
    // Match the route
    for (let i = 0; i < this.routes.length; i++) {
      const item = this.routes[i]
      if (this.currentUrl === item.path) {
        route = item
        break}}// If no match is found, the last route is used
    if(! route) { route =this.routes[this.routes.length - 1]}// Render the current component
    ReactDOM.render(route.component, document.getElementById('root'))}}// Define several routes first
const routes = [
  {
    path: '/'.name: 'home'.component: <Home />}, {path: '/about'.name: 'about'.component: <About />}, {path: The '*'.name: '404'.component: <NotFound404 />,},]new HashRouter(routes)

function Home() {
  return (
    <h1>Home</h1>)}function About() {
  return (
    <h1>About</h1>)}function NotFound404() {
  return (
    <h1>NotFound404</h1>)}Copy the code

The history mode

The history mode uses the method in window.history:

  • Back () : back to the previous route.
  • Forward () : forward to the next route, if any;
  • Go (number) : Enter any route. The positive number indicates forward, and the negative number indicates backward.
  • PushState (obj, title, URL) : advance to the specified URL without refreshing the page;
  • ReplaceState (obj, title, URL) : Replace the current route with the URL without refreshing the page.

All five methods allow you to modify the page URL without sending a request.

If the server does not have a newly updated URL, an error will be reported upon refreshing the browser, because after refreshing the browser, it is actually sending an HTTP web request to the server. Therefore, to use the History route, you need support on the server side.

The first load executes the load event;

Popstate events can listen for back, forward, and GO events.

PushState and replaceState cannot be listened on, so we need to implement them ourselves. Window.dispatchevent is an event trigger that you can use to implement. The following code is a demonstration of the use of window.dispatchEvent:

const listener = function (type) {
  // The original operation to be listened on
  const origin = window.history[type]
  return function () {
    // Arguments are the arguments passed during execution
    const func = origin.apply(this.arguments)
    const newEvent = new Event(type)
    newEvent.arguments = arguments
    window.dispatchEvent(newEvent)
    return func
  }
}
window.history.pushState = listener('pushState')
window.history.replaceState = listener('replaceState')

window.addEventListener('pushState'.(e) = > {
  console.log(e)
}, false)

window.addEventListener('replaceState'.(e) = > {
  console.log(e)
}, false)

window.history.pushState({ text: 'pushState' }, 'pushState'.'/pushState')
window.history.replaceState({ text: 'replaceState' }, 'replaceState'.'/replaceState')
Copy the code

Implement a simple history route

import React from 'react'
import ReactDOM from 'react-dom'

// Define several routes first
const routes = [
  {
    path: '/'.name: 'home'.component: <Home />}, {path: '/about'.name: 'about'.component: <About />}, {path: The '*'.name: '404'.component: <NotFound404 />,},]function Home() {
  return (
    <h1>Home</h1>)}function About() {
  return (
    <h1>About</h1>)}function NotFound404() {
  return (
    <h1>NotFound404</h1>)}class HistoryRouter {
  constructor(routes) {
    this.routes = routes
    this.currentUrl = ' '
    this._refresh = this._refresh.bind(this)
    this._addStateListener()
    window.addEventListener('load'.this._refresh, false)
    window.addEventListener('popstate'.this._refresh, false)
    window.addEventListener('pushState'.this._refresh, false)
    window.addEventListener('replaceState'.this._refresh, false)}_addStateListener() {
    const listener = function (type) {
      // The original operation to be listened on
      const origin = window.history[type]
      return function () {
        // Arguments are the arguments passed during execution
        const func = origin.apply(this.arguments)
        const newEvent = new Event(type)
        newEvent.arguments = arguments
        window.dispatchEvent(newEvent)
        return func
      }
    }
    window.history.pushState = listener('pushState')
    window.history.replaceState = listener('replaceState')}_refresh() {
    this.currentUrl = window.location.pathname
    let route = null
    // Match the route
    for (let i = 0; i < this.routes.length; i++) {
      const item = this.routes[i]
      if (this.currentUrl === item.path) {
        route = item
        break}}// If no match is found, the last route is used
    if(! route) { route =this.routes[this.routes.length - 1]}// Render the current component
    ReactDOM.render(route.component, document.getElementById('root'))}}new HistoryRouter(routes)
Copy the code

If you are using a Webpack development environment, this code will execute normally, even if the page is refreshed, it will return to the page normally, which is handled by the Webpack Dev Server.

If you are using another Web server, you will need to do some configuration yourself.

// If you are using nginx as a web server, you can use the following code to switch the page in the console, but when refreshed, you will get 404
window.history.pushState({}, ' '.'/about') // Display the About screen

window.history.pushState({}, ' '.'/') // Display the home screen

window.history.pushState({}, ' '.'/abc') // Display the NotFound404 interface
Copy the code

In the case of nginx, you can modify the configuration file to return the index.html interface if the page is not found:

The default is: #error_page 404/404.html; The value can be: error_page 404 /index.html;Copy the code

React Router

React Router is divided into three categories: CORE, WEB, and NATIVE, according to reactrouter.com/. CORE is used for the back end, such as node; The WEB is front-end routing; NATIVE is a mobile app. This article will focus on The WEB type Router.

Router

Provided by react-Router, this is a common low-level interface to the Router component. Typically, an application will use one of the higher-order routes:

  • BrowserRouter
  • HashRouter
  • MemoryRouter
  • NativeRouter
  • StaticRouter
import React from 'react'
import ReactDOM from 'react-dom'
import { Router } from 'react-router'
import { createBrowserHistory } from 'history'

const history = createBrowserHistory();

ReactDOM.render(
  <Router history={history}>
    <Home />
  </Router>.document.getElementById('root'))function Home() {
  return (
    <h1>Home</h1>)}Copy the code

BrowserRouter

Routing in History mode, using HTML5’s History API.

Properties:

  • basename
  • forceRefresh
  • GetUserConfirmation and<Prompt>Together with
  • keyLength
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    <>
      <Router
        basename={'/basename'} // After this path is configured, all paths must be prefixed with this prefix. Otherwise, there will be a warning, and the component may not be accessible in some cases >
        <Route path="/">
          <Home />
        </Route>
        <Route path="/about">
          <About />
        </Route>
      </Router>
    </>
  )
}

ReactDOM.render(
  <App />.document.getElementById('root'))function Home() {
  return (
    <h1>Home</h1>)}function About() {
  return (
    <h1>About</h1>)}Copy the code

Visit http://localhost:3000/basename/ to see the Home interface;

Visit http://localhost:3000/basename/about to see the Home and the About interface;

HashRouter

Hash mode routing.

Properties:

  • basename
  • GetUserConfirmation and<Prompt>Together with
  • HashType, default “slash” (#/), can also be “noslash” (#), “hashBang” (#! /)
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    <>
      <Router
        basename={'/basename'} // After this path is configured, all paths must be prefixed with this prefix. Otherwise, there will be a warning, and the component may not be accessible in some cases >
        <Route path="/">
          <Home />
        </Route>
        <Route path="/about">
          <About />
        </Route>
      </Router>
    </>
  )
}

ReactDOM.render(
  <App />.document.getElementById('root'))function Home() {
  return (
    <h1>Home</h1>)}function About() {
  return (
    <h1>About</h1>)}Copy the code

Visit http://localhost:3000/#/basename/ to see the Home screen.

Visit http://localhost:3000/#/basename/about to see the Home and About screens.

MemoryRouter

Cannot read and write address bar urls, used in non-browser environments like React Native. But the browser environment can also be used, such as in this example:

import React from 'react'
import ReactDOM from 'react-dom'
import { MemoryRouter as Router, Route, Link } from 'react-router-dom'

function App() {
  return (
    <>
      <Router
        initialEntries={["/one", "/two", { pathname: "/three"}}]initialIndex={1}
      >
        <Route path="/one">
          <One />
        </Route>
        <Route path="/two">
          <Two />
        </Route>
        <Route path="/three">
          <Three />
        </Route>
        <Link to="/one">one</Link>
        <br />
        <Link to="/two">two</Link>
        <br />
        <Link to="/three">three</Link>
      </Router>
    </>
  )
}

ReactDOM.render(
  <App />.document.getElementById('root'))function One() {
  return (
    <h1>One</h1>)}function Two() {
  return (
    <h1>Two</h1>)}function Three() {
  return (
    <h1>Three</h1>)}Copy the code

Go to http://localhost:3000/ to see the Two interface, and you can click on the link to switch content, but the URL doesn’t change.

Properties:

  • InitialEntries are an array of routing objects. The array fields can be pathname, search, hash, state, or a string URL path
  • InitialIndex initialIndex
  • getUserConfirmation
  • keyLength

NativeRouter

React Native builds a route used by IOS and Android apps.

import { NativeRouter } from 'react-router-native'

<NativeRouter>
  <App />
</NativeRouter>
Copy the code

Properties:

  • GetUserConfirmation and<Prompt>Together with
  • keyLength

StaticRouter

This is a useful one on the server side, where the user never actually clicks, so the location never changes.

Here’s an official node example:

import http from "http";
import React from "react";
import ReactDOMServer from "react-dom/server";
import { StaticRouter } from "react-router";

http
  .createServer((req, res) = > {
    // This context object contains the results of the render
    const context = {};

    const html = ReactDOMServer.renderToString(
      <StaticRouter location={req.url} context={context}>
        <App />
      </StaticRouter>
    );

    // context.url will contain the URL to redirect to if a <Redirect> was used
    if (context.url) {
      res.writeHead(302, {
        Location: context.url
      });
      res.end();
    } else {
      res.write(html);
      res.end();
    }
  })
  .listen(3000);
Copy the code

Properties:

  • basename
  • location: string
  • location: object
  • context: object

Route

The React Router is the most important component of the React Router. Its function is to display the CORRESPONDING UI based on the path match.

Properties:

  • path: string | string []
  • Exact: bool Indicates whether urls are exactly matched
  • Component normal path can only be matched by location, whereas this property can be matched by match, location, history, and so on
  • Render: Func inline render component
  • Children: whether func can match the content to be displayed on the route
  • Strict: bool Path with trailing/can only match urls with trailing /
  • location: object
  • Sensitive: bool Indicates whether the URL is case sensitive

Component and render take precedence over children, so don’t use more than one

Example:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route } from 'react-router-dom'

// All route props (match, location and history) are available to User
function User(props) {
  console.log(props)
  return <h1>Hello {props.match.params.username}!</h1>
}

ReactDOM.render(
  <Router>{/* common path */}<Route path='/mypath'>
      <MyPath />
    </Route>{/* array path */}<Route path={['/arrpath0', '/arrpath1']} >
      <ArrPath />
    </Route>{/* exact match */}<Route exact path='/exact'>
      <Exact />
    </Route>{/* match */}<Route strict path='/strict/'>
      <Strict />
    </Route>{/* case sensitive */}<Route sensitive path='/Sensitive'>
      <Sensitive />
    </Route>{/* component allows components to use more properties */}<Route path='/user/:username' component={User} />{/* render allows inline components */}<Route path='/render' render={()= > <div>Render</div>} /> {/* displays */} whether the route is matched or not<Route children={Children} />
  </Router>.document.getElementById('root'))function MyPath() {
  return (
    <h1>MyPath</h1>)}function Exact() {
  return (
    <h1>Exact</h1>)}function Strict() {
  return (
    <h1>Strict</h1>)}function Sensitive() {
  return (
    <h1>Sensitive</h1>)}function ArrPath() {
  return (
    <h1>ArrPath</h1>)}function Children() {
  return (
    <h1>Children</h1>)}Copy the code

Link

Provides a declarative, accessible navigation link.

  • To: string Indicates the link address in the form of a string
  • To: object Indicates the link address in the form of an object
  • To: function Connection address in the form of a function
  • Replace: bool defaults to false. If true, clicking the link replaces the current entry in the history stack instead of adding a new entry
  • InnerRef: Function accesses the DOM element of the component
  • innerRef: RefObject
  • Component: React.ponent can use its own navigation component
  • Others can pass some attributes, such as ID, title, and className

Example:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

const link5Ref = node= > {
  console.log(node)
}

const link6Ref = React.createRef()

const FancyLink = React.forwardRef((props, ref) = > (
  <a href='/link7' ref={ref}>Link7{props.children}</a>
))

ReactDOM.render(
  <Router>
    <Link to="/link1">Link1</Link>
    <br />
    <Link to={{
      pathname: '/link2',
      search: '?foo=bar',
      hash: '#hello-hash',
      state: {},
    }}>Link2</Link>
    <br />
    <Link to={location= > {console.log(location); return '/link3'}}>Link3</Link>
    <br />{/* window.history.length */}<Link to="/link4" replace>Link4</Link>
    <br />
    <Link to="/link5" innerRef={link5Ref}>Link5</Link>
    <br />
    <Link to="/link6" innerRef={link6Ref}>Link6</Link>
    <br />
    <Link to="/link7" component={FancyLink} />
    <br />
    <Link to="/link8" title="link8" style={{ fontSize: '2rem' }}>Link8</Link>
    <Route path='/link1'>
      <Link1 />
    </Route>
    <Route path='/link2'>
      <Link2 />
    </Route>
    <Route path='/link3'>
      <Link3 />
    </Route>
    <Route path='/link4'>
      <Link4 />
    </Route>
    <Route path='/link5'>
      <Link5 />
    </Route>
    <Route path='/link6'>
      <Link6 />
    </Route>
    <Route path='/link7'>
      <Link7 />
    </Route>
    <Route path='/link8'>
      <Link8 />
    </Route>
  </Router>.document.getElementById('root'))function Link1() {
  return (
    <h1>Link1</h1>)}function Link2() {
  return (
    <h1>Link2</h1>)}function Link3() {
  return (
    <h1>Link3</h1>)}function Link4() {
  return (
    <h1>Link4</h1>)}function Link5() {
  return (
    <h1>Link5</h1>)}function Link6() {
  return (
    <h1>Link6</h1>)}function Link7() {
  return (
    <h1>Link7</h1>)}function Link8() {
  return (
    <h1>Link8</h1>)}Copy the code

NavLink

This is a special version of that can be styled to render elements when it matches the current URL.

  • ActiveClassName: String Class name after activation
  • ActiveStyle: Inline style after an object has been activated
  • Exact: bool Specifies whether the style takes effect only after the URL is exactly matched
  • Strict: bool Path with trailing “/” only matches URL style with trailing “/”
  • IsActive: func adds additional functions to activate this link
  • location: object
  • aria-current: string

Example:

style.css

.selected {
  color: aqua;
}
Copy the code
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, NavLink } from 'react-router-dom'
import './style.css'

const activeSty = {
  color: 'orange'
}

const exactSty = {
  color: 'red'
}

const strictSty = {
  color: 'yellow'
}

const isActiveSty = {
  color: 'bisque'
}

const isActiveFun = (match, location) = > {
  console.log(match)
  console.log(location)
  if(! match) {return false
  }
  return true
}

ReactDOM.render(
  <Router>
    <NavLink to="/navlink1" activeClassName="selected">NavLink1</NavLink>
    <br />
    <NavLink to='/navlink2' activeStyle={activeSty}>NavLink2</NavLink>
    <br />
    <NavLink to='/navlink3' exact activeStyle={exactSty}>NavLink3</NavLink>
    <br />
    <NavLink to='/navlink4/' strict activeStyle={strictSty}>NavLink4</NavLink>
    <br />
    <NavLink to='/navlink5' isActive={isActiveFun} activeStyle={isActiveSty}>NavLink5</NavLink>
    <br />
    <Route path='/navlink1'>
      <NavLink1 />
    </Route>
    <Route path='/navlink2'>
      <NavLink2 />
    </Route>
    <Route path='/navlink3'>
      <NavLink3 />
    </Route>
    <Route path='/navlink4/'>
      <NavLink4 />
    </Route>
    <Route path='/navlink5'>
      <NavLink5 />
    </Route>
  </Router>.document.getElementById('root'))function NavLink1() {
  return (
    <h1>NavLink1</h1>)}function NavLink2() {
  return (
    <h1>NavLink2</h1>)}function NavLink3() {
  return (
    <h1>NavLink3</h1>)}function NavLink4() {
  return (
    <h1>NavLink4</h1>)}function NavLink5() {
  return (
    <h1>NavLink5</h1>)}Copy the code

Prompt

Prompt means Prompt and is used to give the user some information before the location jump. This parameter is used with getConfirmation of the Router.

  • Message: string Indicates the message
  • Message: func needs to return a string to prompt the user, or true to allow a direct jump
  • When: bool false is not displayed, true is displayed

Example:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Prompt, Link } from 'react-router-dom'

const getConfirmation = (message, callback) = > {
  // this is the default behavior
  const allowTransition = window.confirm(message)
  console.log(allowTransition)
  callback(allowTransition)
}

const promptFunc = (location, action) = > {
  console.log(location)
  console.log(action)
  if (action === 'PUSH') {
    return "Are you sure you want to leave home?"
  } 
  if (action === 'POP') {
    return "Are you sure you want to leave prompt?"
  }
}

ReactDOM.render(
  <Router getUserConfirmation={getConfirmation}>
    <div>{/ *<Prompt when={true} message="Are you sure you want to leave?" />* /}<Prompt when={true} message={promptFunc} />
      <Link to="/prompt">Prompt</Link>
      <Route path="/" exact>
        <Home />
      </Route>
      <Route exact path="/prompt" component={Prompt1} />
    </div>
  </Router>.document.getElementById('root'))function Home() {
  return (
    <h1>Home</h1>)}function Prompt1() {
  return (
    <h1>Prompt1</h1>)}Copy the code

Redirect

Will navigate to a new location that will override the current entry in the history stack, just like a server-side redirect (HTTP 3xx). Can only be used in

.

  • To: string URL path
  • To: object The URL path in the form of an object
  • Push: bool If true, the redirection pushes the new location into the history, rather than replacing the current entry
  • From: string URL path
  • Exact: bool Indicates whether urls are exactly matched
  • Strict: bool Path with trailing/can only match urls with trailing /
  • Sensitive: bool Indicates whether the URL is case sensitive

Example:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom'

ReactDOM.render(
  <Router>
    <Switch>
      <Redirect from="/one" to="/home1" />
      <Redirect exact from="/two" to="/home2" />
      <Redirect strict from="/three/" to="/home3" />
      <Redirect sensitive from="/Four" to="/home4" />
      <Route path="/home1">
        <Home1 />
      </Route>
      <Route path="/home2">
        <Home2 />
      </Route>
      <Route path="/home3">
        <Home3 />
      </Route>
      <Route path="/home4">
        <Home4 />
      </Route>
      <Route path="/five">
        <Redirect to="/home1" />
      </Route>
    </Switch>
  </Router>.document.getElementById('root'))function Home1() {
  return (
    <h1>Home1</h1>)}function Home2() {
  return (
    <h1>Home2</h1>)}function Home3() {
  return (
    <h1>Home3</h1>)}function Home4() {
  return (
    <h1>Home4</h1>)}Copy the code

Switch

Use to render the first child

or

If only

is used, all routes matching the path will be rendered. If

is used, only one Route will be rendered.

  • location: object
  • children: node

Example:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

ReactDOM.render(
  <Router>
    <Route path="/">
      <Route1 />
    </Route>
    <Route path="/route2">
      <Route2 />
    </Route>
    <Switch>
      <Route path="/">
        <Switch1 />
      </Route>
      <Route path="/route2">
        <Switch2 />
      </Route>
    </Switch>
  </Router>.document.getElementById('root'))function Route1() {
  return (
    <h1>Route1</h1>)}function Route2() {
  return (
    <h1>Route2</h1>)}function Switch1() {
  return (
    <h1>Switch1</h1>)}function Switch2() {
  return (
    <h1>Switch2</h1>)}Copy the code

Go to http://localhost:3000/route2

All the routes outside the

match, but the routes inside the

match only one.

Common properties and methods

generatePath

import { generatePath } from "react-router";

const path = generatePath("/user/:id/:entity(posts|comments)", {
  id: 1.entity: "posts"
});
console.log(path) // /user/1/posts
Copy the code

location

{
  key: 'ac3df4'.// not with HashHistory!
  pathname: '/somewhere'.search: '? some=search-string'.hash: '#howdy'.state: {
    [userDefined]: true}}Copy the code

matchPath

import { matchPath } from "react-router";

matchPath("/users/2", {
  path: "/users/:id".exact: true.strict: true
});

//  {
// isExact: true
// params: {
// id: "2"
/ /}
// path: "/users/:id"
// url: "/users/2"
/ /}
matchPath("/users", {
  path: "/users/:id".exact: true.strict: true
});

// null
Copy the code

withRouter

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, withRouter } from 'react-router-dom'

export const ButtonWithRouter = withRouter(({ history }) = > {
  console.log('history', history)
  return (
    <button
      type='default'
      onClick={()= > { history.push('/home') }}
    >
      Click Me!
    </button>

  )
})

ReactDOM.render(
  <>
    <Router>
    <ButtonWithRouter />
      <Route path="/home">
        <Home1 />
      </Route>
    </Router>
  </>.document.getElementById('root'))function Home1() {
  return (
    <h1>Home1</h1>)}Copy the code

history

history

match

match

path-to-regexp

Rules for URL parameters. The status of the page is defined by URL parameters as far as possible.

path-to-regexp

Hooks

useHistory

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, useHistory } from 'react-router-dom'

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

ReactDOM.render(
  <>
    <Router>
    <HomeButton />
      <Route path="/home">
        <Home1 />
      </Route>
    </Router>
  </>.document.getElementById('root'))function Home1() {
  return (
    <h1>Home1</h1>)}Copy the code

useLocation

import React, { useEffect } from 'react'
import ReactDOM from 'react-dom'
import {
  BrowserRouter as Router,
  Switch,
  useLocation,
  Route,
} from "react-router-dom"

function App() {
  let location = useLocation()
  useEffect(() = > {
    console.log(location)
  }, [location])
  return (
    <Switch>
      <Route path="/home">
        <Home1 />
      </Route>
    </Switch>
  )
}

ReactDOM.render(
  <Router>
    <App />
  </Router>.document.getElementById('root'))function Home1() {
  return (
    <h1>Home1</h1>)}Copy the code

useParams

import React from 'react'
import ReactDOM from 'react-dom'
import {
  BrowserRouter as Router,
  Switch,
  useParams,
  Route,
} from "react-router-dom"

function BlogPost() {
  let { slug } = useParams()
  return <div>Now showing post {slug}</div>
}

ReactDOM.render(
  <Router>
    <Switch>{/* visit http://localhost:3000/ */}<Route exact path="/">
        <HomePage />
      </Route>Visit http://localhost:3000/blog/xxx {/ * * /}<Route path="/blog/:slug">
        <BlogPost />
      </Route>
    </Switch>
  </Router>.document.getElementById('root'))function HomePage() {
  return (
    <h1>Home</h1>)}Copy the code

useRouteMatch

import React from 'react'
import ReactDOM from 'react-dom'
import {
  BrowserRouter as Router,
  useRouteMatch,
} from "react-router-dom"

function BlogPost() {
  let match = useRouteMatch("/blog/:slug")
  // Do whatever you want with the match...
  console.log(match)
  return (
    <h1>Home, { match? .params? .slug }</h1>
  )
}

ReactDOM.render(
  <Router>
    <BlogPost />
  </Router>.document.getElementById('root'))Copy the code

Embedded routines by

import React from 'react'
import ReactDOM from 'react-dom'
import {
  BrowserRouter as Router,
  Link,
  Route,
} from "react-router-dom"

function Level1() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/level1/1">Level1-1</Link>
          </li>
          <li>
            <Link to="/level1/2">Level1-2</Link>
          </li>
          <li>
            <Link to="/level1/3">Level1-3</Link>
          </li>
        </ul>

        <div>
          <Route path="/level1/:id" component={Level2} />
        </div>
      </div>
    </Router>)}function Level2(props) {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to={` /level1/ ${props.match.params.id} /level2/1`} >Level2-1</Link>
          </li>
          <li>
            <Link to={` /level1/ ${props.match.params.id} /level2/2`} >Level2-2</Link>
          </li>
          <li>
            <Link to={` /level1/ ${props.match.params.id} /level2/3`} >Level2-3</Link>
          </li>
        </ul>

        <div>
          <Route path="/level1/:id/level2/:subId" component={SubComponent} />
        </div>
      </div>
    </Router>)}function SubComponent(props) {
  return (
    <h1>{`Level ${props.match.params.id} - ${props.match.params.subId}`}</h1>
  )
}

ReactDOM.render(
  <Router>
    <Level1 />
  </Router>.document.getElementById('root'))Copy the code