Routes in React

An overview of the

What is a route

Routing is a single page development solution (SPA). Using routing, you can jump to a page without refreshing the page, which is closer to the native application

How to use

There are two types of routing: declarative and programmatic

What problem to solve

Relying on packages makes it possible to jump to a page without refreshing the page

Under the bag

yarn add react-router-dom

yarn add react-router-dom@5.21.Note: Different versions of the router use different modesCopy the code

Declarative navigation

The basic use

Declarative navigation uses the form of components to implement route jumps

Import {BrowserRouter as Router,Route,Link} class Login extends React.Component {render () {<div> I am Login component </div>}} Render () {return (<BrowserRouter> <Link to="/login"> </Link> <Route path="/login" component={Login}></Route> </BrowserRouter> ) } }Copy the code

Note: Route and Link components must be placed in BrowserRouter or HashRouter

Match rule

Fuzzy matching

In react-router-DOM matching, fuzzy matching is adopted by default, which means that the same route components are rendered together when the route address begins

Such as:

Import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component {render () {return Demo1</div> Render () {return Demo2</div>}} Class App extends React.Component {render () {return Demo2</div>}} Render () {return (<BrowserRouter> <Link to="/demo/1"> = Demo1</Link> <Link to="/demo/2"> = Demo2</Link> <Route path="/demo" component={Demo1}></Route> <Route path="/demo" component={Demo2}></Route> </BrowserRouter> ) } }Copy the code

As long as the path in Route starts with the same pathname in location, such as login and /, or /demo/first and /demo, the fuzzy match will succeed and all routes will be rendered

Precise matching

The solution to fuzzy matching is to match only if the path is exactly the same as the PathName, rendering the component

import {BrowserRouter as Router,Route,Link}

class Demo1 extends React.Component {
    render () {
        return <div>I am not</div>}}class App extends React.Component {
    render () {
        return (
        	<BrowserRouter>
            	<Link to="/demo/1">Some I not to go</Link>
                <Route exact path="/demo" component={Demo1}></Route>
            </BrowserRouter>)}}Copy the code

In this case, the match fails because the exact attribute is added. That is, the path must be exactly the same as the pathname of the page

404

The 404 solution takes advantage of the Route unconditional feature without adding a path

Import {BrowserRouter as Router,Route,Link} class notFount extends React.Component {render () {return (<div> I am 404 Component </div>)}} class App extends React.Component {render () {return (<BrowserRouter> <Route component={notFount}></Route> </BrowserRouter> ) } }Copy the code

The routing component renders the component unconditionally as long as it does not add the path attribute

Common components

In react-router-DOM, there are a number of functional components, such as

Highlighting NavLink

<NavLink to="/login" activeClassName="router-link-active">Copy the code

BrowserRouter

The wrap routing component, which can have only one BrowserRouter per page, uses a route in History mode

Import {BrowserRouter,Route,Link} from 'react-route-dom' <BrowserRouter> <Link to="/login"> Login </Link> <Route path="/login" component={Login}></Route> </BrowserRouter>Copy the code

HashRouter

Routes in hash mode are used

Import {HashRouter,Route,Link} from 'react-route-dom' <HashRouter> <Link to="/login"> </Link> <Route path="/login" component={Login}></Route> </HashRouter>Copy the code

Route

It is used as a placeholder for the Route component. The matched Route component replaces the Route component

Import {HashRouter,Route,Link} from 'react-route-dom' <HashRouter> <Link to="/login"> </Link> <Route path="/login" exact component={Login}></Route> </HashRouter>Copy the code

You can use the exact attribute to achieve exact matching

Link

The jump component of declarative navigation, through which pages can be jumped

Import {HashRouter,Route,Link} from 'react-route-dom' <HashRouter> <Link to="/login"> </Link> <Route path="/login" exact component={Login}></Route> </HashRouter>Copy the code

Redirect

Redirection component that enables redirection of routing addresses

The import {HashRouter, Route, Link, Redirect} from 'react - the Route - dom' < HashRouter > < Link to = "/ login" > login < / Link > < Redirect from="/" to="/dashbord"></Redirect> <Route path="/login" exact component={Login}></Route> </HashRouter>Copy the code

Failure after jump

Switch

Switch is designed to solve the problem of fuzzy matching, in which the routing matching rules wrapped around this component will render only the first successful matching component

The import {HashRouter, Route, Link, Redirect, Switch} from 'react - the Route - dom' < HashRouter > < Link to = "/ login" > login < / Link > < Redirect  from="/" to="/dashbord"></Redirect> <Switch> <Route path="/login" exact component={Login}></Route> </Switch> </HashRouter>Copy the code

6.0+ solution

The 6.0+ react-router-dom usage has changed slightly

Import {BrowserRoter as Router,Routes, Routes, Link} <Router> <Link to="/login"> </Link> <Routes> <Route path="/login" element={<Login></Login>}></Route> </Routes> </Router>Copy the code

Programmatic navigation

jump

Programmatic navigation uses the props. History. Push method to jump

import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component { render () { return <button OnClick ={()=>{this.props.history.push('/ button ')}} class App extends React.Component {render () { </Link> <Route exact path="/demo" component={Demo1}></Route> </BrowserRouter> ) } }Copy the code

The fallback

The fallback also leverages the method in props

import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component { render () { return <button OnClick ={()=>{this.props.history.go(-1)}}> </button>}} class App extends React.Component {render () {return () </Link> <Route exact path="/demo" component={Demo1}></Route> </BrowserRouter> )}}Copy the code

Dynamic routing

Dynamic routing is actually the form of route parameter transmission, and the matching rule is the value of the dynamic attribute of the route parameter

Import {BrowserRouter as Router, </Link> <Route path="/dashbord/:userId"></Route> </Router>Copy the code

Routing and the cords

Declarative navigation

Query parameter transmission parameters

Passing parameters
import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component { render () { return <button OnClick ={()=>{this.props.history.go(-1)}}> </button>}} class App extends React.Component {render () {return () <BrowserRouter> <Link to="/demo1? </Link> <Route exact path="/demo" component={Demo1}></Route> </BrowserRouter>)}}Copy the code
Receive parameters
thisThe.props. Location. search parameter is a string of data that needs to be manually converted to object formatthis.props.location.search
    .slice(1)
    .split("&")
    .map((item) = > {
    const target = item.split("=");
    return { [target[0]]: target[1]}; })Copy the code

Route parameters are transmitted

Passing parameters
import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component { render () { return <button OnClick ={()=>{this.props.history.go(-1)}}> </button>}} class App extends React.Component {render () {return () <BrowserRouter> <Link to={{pathName :'/demo/123',a:{aa:123123}}}> component={Demo1}></Route> </BrowserRouter> ) } }Copy the code
Receive parameters
this.props.match.params.id
Copy the code

Note: All key-value pairs in the object are brought to this.props. Location

Programmatic navigation

Query parameter transmission parameters

Passing parameters
import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component { render () { return <button onClick={()=>{this.props.history.push('/login? </button>}} class App extends React.Component {render () {return (<BrowserRouter> <Link To ={{pathName :'login',params:{id:123}}}> </Link> <Route path="/demo" component={Demo1}></Route> </BrowserRouter> ) } }Copy the code
Receive parameters
This. Props. The location. The search parameter is a string, Need to manually convert data object format this. Props. Location. Search. Slice (1). The split (" & "). The map ((item) = > {const target = item. The split (" = "); return { [target[0]]: target[1] }; })Copy the code

Routing parameters

Passing parameters
import {BrowserRouter as Router,Route,Link} class Demo1 extends React.Component { render () { return <button OnClick ={()=>{this.props.history. Push ({path:'/login/' + '123'})}}> </button>}} class App extends React.Component { Render () {return (<BrowserRouter> <Link to={{pathname:'/demo/123',params:{id:123}}}> </Link> <Route exact path="/demo/:id" component={Demo1}></Route> </BrowserRouter> ) } }Copy the code
Receive parameters
this.props.match.params.id
Copy the code

Pass and summarize

Query parameter transmission parameters

Query parameters can be passed directly by adding attributes to the query object in

You can simply use the this.props. Location. Parameter name. attribute

Route parameters are transmitted

Route parameters need to be defined in advance, and instead of being carried to this.props. Location, they will be stored in this.mate.params. Parameter name. Property

Seatch mass participation

Is the search parameter passed by? Strings that begin with a sign, ampersand, and = are concatenated to the end of the address and need to be manually converted to an object

The state transfer and

The state parameter is transmitted as the query parameter

Cross domain

Package node configuration

Because webpack.config.js is not generated in create-react-app, the proxyServer plug-in cannot be added to enable the proxy service

The proxy node can be configured in package.json

"proxy":"Server address"
Copy the code

SetupProxy configuration

Instead of being configured in package.json, you can use third-party packages to implement cross-domain HTTP-proxy-middleware

const proxy  = require('http-proxy-middleware')

module.exports (app) => {
    app.use(
        proxy('/api', {target:'Server address'.changeOrigin:true // Allow cross-domain}}))Copy the code

Routing principle

Hash pattern

import React from "react"; import "./App.css"; class Demo1 extends React.Component { render() { console.log(this.props); Return (<div> <p> I am Demo1</p> </div>); } } class Demo2 extends React.Component { render() { console.log(this); Return <div> I am Demo2</div>; } } class App extends React.Component { state = { componentName: "", }; componentDidMount() { window.addEventListener("hashchange", (event) => { this.setState((newState) => { return { componentName: window.location.hash.slice(1), }; }); }); Render () {return (<div> <button onClick={() => (window.location.hash = "/demo1")}> render() {return (<div> <button onClick={() => (window.location.hash = "/demo1")} OnClick = {() = > (window. The location. The hash = "/ demo2")} > point me to demo2 < / button > {(this.state.com ponentName = = = "/ not" | | window.location.hash.slice(1) === "/demo1") && <Demo1></Demo1>} {(this.state.componentName === "/demo2" || window.location.hash.slice(1) === "/demo2") && <Demo2></Demo2>} </div> ); } } export default App;Copy the code

The history mode

import React from "react"; import "./App.css"; Render () {return (<div> <p> <div>); render(<div> <div>); }} class Demo2 extends ponent {render() {return Demo2</div>; } } class App extends React.Component { state = { componentName: "", }; componentDidMount() { window.addEventListener("popstate", (event) => { console.log(event); }); } render() {const render = () => {// Render () {this.forceupdate (); }; return ( <div> <button onClick={() => { window.history.pushState({}, "", "/demo1"); render(); Me to not}} > < / button > < button onClick = {() = > {window. History. PushState ({}, "","/demo2 "); render(); </button> {window.location. pathName === "/demo1" && < demo1 ></ demo1 >} {window.location. pathName === "/demo2" && <Demo2></Demo2>} </div> ); } } export default App;Copy the code