Come and join us!

“The Newbies of Little and Hill” provides technical information and a series of basic articles for front-end developers. For a better user experience, please move to our official website of Xiaoheshan beginners (https://xhs-rookies.com/) to learn, timely access to the latest articles.

“Code tailor”, if you are interested in our articles or would like to make some suggestions, please follow our official account “newbies of Xiaoheshan” at WeChat, and contact us. You can also view our articles on WeChat. Every suggestion or approval is a great encouragement to us

preface

In this section we will cover the React -Router configuration in React and how to use it.

This article will introduce you to the following:

  • knowreact-router
  • react-routerThe basic use
  • react-routerUse advanced
  • react-router-config

Know the react – the router

Understand front-end routing

Routing is actually a term used in network engineering: two of the most important devices in the architecture of a network are routers and switches.

Of course, the router is more and more well-known in our production, because we all use it in our daily life:

  • In fact, the router mainly maintains a mapping table;
  • The mapping table determines where the data goes;

The concept of routing was first implemented in back-end routing because the development of the Web has mainly gone through such phases:

  • Backend routing phase;
  • Front and rear end separation stage;
  • Single page rich application (SPA);

Phase 1: Backend routing phase

In the early days of web development, the entire HTML page was rendered by the server.

  • The server directly produces the corresponding renderHTMLPage, returned to the client for presentation.

But, a website, so many pages how to handle the server?

  • A page has its own corresponding URL, i.eURL.
  • URLIt will be sent to the server, and the server will check it with the regexURLMake a match, and give it to one lastControllerTo process.
  • ControllerAll kinds of processing, and finally generatedHTMLOr data, back to the front end.
  • So that completes oneIOOperation.

The above operation is called back-end routing.

  • When we need to request different path content in the page, we give it to the server for processing, the server renders the whole page, and returns the page to the client.
  • In this case the rendered page does not need to load any separatelyjscss, can be presented directly to the browser, which also helpsSEOThe optimization.

Disadvantages of back-end routing:

  • In one case, the modules of the entire page are written and maintained by back-end people.
  • The other scenario is that the front-end developer, if he wants to develop the page, needs to go throughPHPJavaAnd other languages to write the page code.
  • And usuallyHTMLCode and data and corresponding logic get mixed up, and writing and maintaining them is a terrible thing.

Stage 2: Front and rear end separation stage

The understanding of front-end rendering:

  • Static resources involved in each request are retrieved from the Static Resource Server. These resources includeHTML+CSS+JS, and then render the requested resources in the front end;
  • Note that every time a client requests a file, it will request a file from a static resource server.
  • Also, as you can see, unlike the previous back-end route, the back-end is only responsible for providing itAPIA;

Front and rear end separation stage:

  • As theAjaxThe emergence of the front and back end separation of the development mode;
  • The back end is provided onlyAPITo return the data, the front end passes throughAjaxGets the data, and can passJavaScriptRender the data to the page;
  • The biggest advantage of this approach is the clarity of responsibilities for the back end, which focuses on data, and the front end, which focuses on interaction and visualization.
  • And when mobile (iOS/Android), the back end does not need to do any processing, it still uses the previous setAPICan;
  • At present, many websites still adopt this mode of development (jQueryDevelopment mode);

Stage 3: Single Page Rich Application (SPA)

Single page rich application understanding:

  • Single page rich application English issingle-page applicationSPA for short;
  • The wholeWebThe application only actually has only one page, whenURLWhen a change occurs, no new static resources are requested from the server;
  • But by JavaScriptListening to theURLAnd according toURLTo render the new page;

How can you apply URLs and rendered pages? The front-end routing

  • Front-end routing is maintainedURLAnd the rendering page mapping relationship;
  • The route can vary according to theURLAnd finally let our framework (e.gVue,React,Angular) to render different components;
  • What we end up seeing on the page is actually a rendered component page;

Front-end Routing Principles

How does the front-end route map the URL to the content? Listen for URL changes.

The URL hash

  • URLhashThis is the anchor point (#), essentially changewindow.locationhref Properties;
  • We can do this by direct assignmentlocation.hashTo change thehref, but the page does not refresh;
<div id="app"> <a href="#/home">home</a> <a href="#/about">about</a> <div class="router-view"></div> </div> <script> // 1. Router-view const routerViewwel = document.querySelector('.router-view') // 2. Listener for hashChange window.addEventListener(' hashChange ', () = bb0 {switch (location.hash) {case '#/home': routerViewEl.innerHTML = 'home' break case '#/about': routerViewEl.innerHTML = 'about' break default: routerViewEl.innerHTML = 'default' } }) </script>

The advantage of hash is that it is more compatible and works in older versions of Internet Explorer, but the drawback is that it has a # that doesn’t look like a real path.

It’s History

The History interface is a new addition to HTML5 and has six modes for changing URLs without refreshing the page:

  • replaceState: replace the original path;
  • pushState: Use the new path;
  • popState: Path backoff;
  • go: To change the path forward or backward;
  • forword: to change the path forward;
  • back: change path backward;

Here’s a brief demonstration of a few methods:

<div id="app"> <a href="/home">home</a> <a href="/about">about</a> <div class="router-view"></div> </div> <script> // 1. Router-view const routerViewwel = document.querySelector('.router-view') // 2. Monitor all the elements of a const aEls = document. The getElementsByTagName (' a ') for (let aEl of aEls) {aEl. AddEventListener (' click ', (e) => { e.preventDefault() const href = aEl.getAttribute('href') console.log(href) history.pushState({}, '', href) historyChange() }) } // 3. Listener for popState and Go operation window.addEventListener(' popState ', historyChange) window.addEventListener(' Go ', historyChange) // 4. Function HistoryChange () {switch (location.pathname) {case '/home': routerViewEl.innerHTML = 'home' break case '/about': routerViewEl.innerHTML = 'about' break default: routerViewEl.innerHTML = 'default' } } </script>

react-router

At present, the three popular front-end frameworks have their own routing implementation:

  • AngularngRouter
  • ReactReactRouter
  • Vuevue-router

Since version 4 of the React Router, routes are no longer managed in a single package:

  • react-routerrouterThe core part of the code;
  • react-router-domIt’s for the browser;
  • react-router-nativeIt’s for native applications;

The latest React Router version is V5:

  • In factv4The version andv5There is not much difference between the versions of the

Install the react – the router:

  • The installationreact-router-domIt will automatically help us install itreact-routerRely on;
yarn add react-router-dom

Note:The following content is the React – Router V5 version of the use and API, if the reader is not currently using the same, please use the official website
react-router

React – Router basic use

Router Basic Usage

The main API for React – Router is the set of components it provides:

BrowserRouterHashRouter

  • Router Contains listening for path changes and passes the corresponding path to child components.
  • BrowserRouterUse the History pattern;
  • HashRouter usehashMode;

The Link and NavLink:

  • The usual path of the jump is usedLinkComponent will eventually be rendered asaElements;
  • NavLinkIs in theLinkSome style attributes are added on top of this (later);
  • toProperties:LinkSet the path to which to jump.

The Route:

  • RouteFor path matching;
  • pathProperty: used to set the path to match;
  • componentProperty: Sets the rendered component after matching to the path;
  • exact: Precise matching, the corresponding component will be rendered only when the exact matching path is exactly the same;

Carry out the following exercise in the APP:

import React, { PureComponent } from 'react' import { BrowserRouter, Route, Link } from 'react-router-dom' import Home from './pages/home' import About from './pages/about' import Profile from './pages/profile' export default class App extends PureComponent { render() { return ( <BrowserRouter> <Link To = "/" > Home page < / Link > < Link to = "/ about" > about < / Link > < Link to = "/ profile" > I < / Link > < the Route exact path = "/" component = {Home} / > <Route path="/about" component={About} /> <Route path="/profile" component={Profile} /> </BrowserRouter> ) } }

The use of NavLink

When the path is selected, the corresponding a element turns red

At this point, we will use the NavLink component instead of the Link component:

  • activeStyle: Style when active (when matching);
  • activeClassName: Class added while active;
  • exact: Whether it is accurately matched;

To demonstrate the ActiveStyle:

<NavLink to="/" activeStyle={{color: "red"}} bb0 Home </NavLink to="/about" activeStyle={{color: ="/"} "Red "}}> about </NavLink> <NavLink to="/profile" activeStyle={{color: "red"}}> my </NavLink>

However, we will notice that when the About or Profile is selected, the first one will also turn red:

  • The reason is that the/path is also matched/about/profile;
  • At this time, we can in the firstNavLinkTo add onexactProperties;
<NavLink exact to="/" activeStyle={{ color: 'red' }}>
  首页
</NavLink>

Default ActiveClassName:

  • In fact, when the default match is successful,NavLinkI’ll add a dynamic oneactive class;
  • So we can also write styles directly
a.active {
  color: red;
}

Of course, if you’re worried about the class being used elsewhere and cascading styles, you can also customize the class

< eXact ="/" eXact ="link-active"> </ eXact ="/" ActiveClassName ="link-active"> About </NavLink> <NavLink to="/profile" ActiveClassName ="link-active"> My </NavLink>

The role of the Switch

Let’s look at the following routing rules:

  • When we match to a certain path, we find that there are some problems;
  • Such as/aboutAnd at the same time that the path is matched,/:useridIt was also matched, and the last oneNoMatchComponents are always matched to;
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/profile" component={Profile} />
<Route path="/:userid" component={User}/>
<Route component={NoMatch}/>

The reason? By default, any component in the React -Router that matches the Route to is rendered;

But in practice, we tend to want to have an exclusivity:

  • Once you get to the first one, you shouldn’t be able to match any more;
  • We can use it at this timeSwitchLet’s take all of thisRouteCarries on the parcel can;
<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/profile" component={Profile} />
  <Route path="/:userid" component={User} />
  <Route component={NoMatch} />
</Switch>

The use of the Redirect

Redirect is used to Redirect a route, and when this component appears, it performs a jump to the corresponding to path:

Here’s an example of how to use this:

  • The user jumps toUserInterface;
  • But in theUserThe interface has oneisLoginTo record whether the user is logged in or not:
  • True: then display the name of the user;
  • False: Redirect directly to the login screen;

App.js defines the Route corresponding to the Login page in advance:

<Switch> ... Other Route <Route path="/login" component={login} /> <Route component={noMatch} /> </Switch>

Write the corresponding logical code in User.js:

import React, { PureComponent } from 'react' import { Redirect } from 'react-router-dom' export default class User extends PureComponent { constructor(props) { super(props) this.state = { isLogin: false, } } render() { return this.state.isLogin ? (</div> </div> </div>) : (<Redirect to="/login" />)}}

React – Router Advanced Use

Nested routing

In development, there are nested relationships between routes.

Let’s assume that there are two pages in the About page:

  • Product list and message list;
  • Click on different links can jump to different places, display different content;
import React, { PureComponent } from 'react' import { Route, Switch, Link} from 'react-router-dom' function aboutProduct (props) {return (<ul> <li> </li> </li> <li> </li> </ul>)} function aboutMessage (props) {return (<ul> </li> </li> <li> </li> </ul>)} export Default class About extends PureComponent {render() {return (<div> <Link to="/ About "> </Link> <Link To ="/about/message"> </Link> <Switch> <Route exact path="/about" component={aboutProduct} /> <Route path="/about/message" component={AboutMessage} /> </Switch> </div> ) } }

Manual jump

So far the jump we’ve implemented is mainly through Link or NavLink, in fact we can also jump through JavaScript code.

But there is one prerequisite for jumping through JavaScript code: you must get the History object.

How can we get the history object? One of two ways

  • Option 1: If the component is wrapped by a routing component, it can be retrieved directlyhistory,location,matchObjects, such as:this.props.history;
import { Route, Switch, NavLink, Class App extends PureComponent {render() {render();}} from 'react-router-dom'; Console. log(this.props. History) return (<BrowserRouter> <button onClick={(E) => this.pushToProfile()}> My </button> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/profile" component={Profile} /> <Route path="/:userid" component={User} /> <Route component={NoMatch} /> </Switch> </BrowserRouter> ) } pushToProfile() { this.props.history.push('/profile') } } export default App
  • Option 2: If the component is a normal rendered component, then it needs to be availablereact-routerAdvanced components providedwithRouterAdd related properties for our component
import { Route, Switch, NavLink, Class App extends PureComponent {render() {render();}} from 'react-router-dom'; Console. log(this.props. History) return (<div> <button onClick={(e) => this.pushToProfile()}> My </button> <Switch> <Route  exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/profile" component={Profile}  /> <Route path="/:userid" component={User} /> <Route component={NoMatch} /> </Switch> </div> ) } pushToProfile() { this.props.history.push('/profile') } } export default withRouter(App)

Passing parameters

There are three ways to pass parameters:

  • Dynamic routing method;
  • searchPassing parameters;
  • toThe incoming object

Dynamic routing

The concept of dynamic routing refers to the fact that paths in a route are not fixed:

  • Such as/detailthepathCorresponding to a componentDetail;
  • If we were topathRouteWhen I match, I write/detail/:id, then/detail/abc,/detail/123Can be matched to thatRouteAnd display;
  • This matching rule is called dynamic routing;

In general, dynamic routing allows you to pass parameters to a route.

<div> ... Link <NavLink to="/detail/abc123"> </NavLink> <Switch>... Route <Route path="/detail/:id" component={detail} /> <Route component={noMatch} /> </Switch> </div>

The detail.js code is as follows:

  • We can go straight throughmatchFetch in an objectid;
  • We’re not using it herewithRouterThe reason is thatDetailIt is wrapped by routing components;
import React, { PureComponent } from 'react'

export default class Detail extends PureComponent {
  render() {
    console.log(this.props.match.params.id)

    return (
      <div>
        <h2>Detail: {this.props.match.params.id}</h2>
      </div>
    )
  }
}

Search Passing Parameters

NavLink writing:

  • We added some in the path of the jumpqueryParameters;
<NavLink to="/detail2? </NavLink> <Switch> <Route path="/detail2" component={detail2}/> </Switch>

How do I get that in Detail2?

  • Detail2In is needed inlocationTo derivesearch;

Note:this
searchIt’s not resolved, we have to resolve it ourselves;

import React, { PureComponent } from 'react' export default class Detail2 extends PureComponent { render() { console.log(this.props.location.search) // ? name=why&age=18 return ( <div> <h2>Detail2:</h2> </div> ) } }

To pass in an object

To can be passed directly to an object

<NavLink to={{pathname: '/detail2', query: {name: 'Kobe ', age: 30}, state: {height: 1.98, address:' Los Angeles'}, search: '? Apikey =123',}} > </NavLink>

Get parameters:

import React, { PureComponent } from 'react'

export default class Detail2 extends PureComponent {
  render() {
    console.log(this.props.location)

    return (
      <div>
        <h2>Detail2:</h2>
      </div>
    )
  }
}

react-router-config

Currently, all of our Route definitions are done directly using the Route component and adding properties.

However, this approach can make routing very confusing, and we want to centralize all routing configurations in one place:

  • You can use it at this timereact-router-configTo complete;

Install the react – the router – config:

yarn add react-router-config

Router /index.js:

import Home from '.. /pages/home' import About, { AboutMessage, AboutProduct } from '.. /pages/about' import Profile from '.. /pages/profile' import Login from '.. /pages/login' import User from '.. /pages/user' import Detail from '.. /pages/detail' import Detail2 from '.. /pages/detail2' import NoMatch from '.. /pages/nomatch' const routes = [ { path: '/', exact: true, component: Home, }, { path: '/about', component: About, routes: [ { path: '/about', exact: true, component: AboutProduct, }, { path: '/about/message', component: AboutMessage, }, ], }, { path: '/profile', component: Profile, }, { path: '/login', component: Login, }, { path: '/user', component: User, }, { path: '/detail/:id', component: Detail, }, { path: '/detail2', component: Detail2, }, { component: NoMatch, }, ] export default routes

Replace the Switch configuration with the renderRoutes function provided in the react-router-config:

{
  renderRoutes(routes)
}

{
  /* <Switch>
     <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/profile" component={Profile} />
      <Route path="/user" component={User} />
      <Route path="/login" component={Login} />
      <Route path="/detail/:id" component={Detail}/>
      <Route path="/detail2" component={Detail2}/>
      <Route component={NoMatch} />
 </Switch> */
}

If it is a child component that requires a route jump, then use the RenderRoutes function in the child component:

  • There will be one more routing component in the jump tothis.props.routeProperties;
  • therouteProperty represents the route object to which the current jump is made and can be retrieved through this propertyroutes;
Export default class About extends PureComponent {render() {return (<div> <Link to="/ About "> </Link> <Link To ="/about/message"> message </Link> {renderRoutes(this.props. Route.routes)} </div>)}

There is actually a matchRoutes helper function provided in the react-router-config:

  • matchRoutes(routes, pathname)Pass in an array of routing objects to get all the matched paths.

Next day forecast

In this section, we learned about the React-Router components and how they complement each other. So far, we have learned all about React. In the next section, we will add a login function to the previous message board!