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:
- know
react-router
react-router
The basic usereact-router
Use advancedreact-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 render
HTML
Page, 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.e
URL
. URL
It will be sent to the server, and the server will check it with the regexURL
Make a match, and give it to one lastController
To process.Controller
All kinds of processing, and finally generatedHTML
Or data, back to the front end.- So that completes one
IO
Operation.
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 separately
js
和css
, can be presented directly to the browser, which also helpsSEO
The 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 through
PHP
和Java
And other languages to write the page code. - And usually
HTML
Code 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 include
HTML+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 it
API
A;
Front and rear end separation stage:
- As the
Ajax
The emergence of the front and back end separation of the development mode; - The back end is provided only
API
To return the data, the front end passes throughAjax
Gets the data, and can passJavaScript
Render 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 setAPI
Can; - At present, many websites still adopt this mode of development (
jQuery
Development mode);
Stage 3: Single Page Rich Application (SPA)
Single page rich application understanding:
- Single page rich application English is
single-page application
SPA for short; - The whole
Web
The application only actually has only one page, whenURL
When a change occurs, no new static resources are requested from the server; - But by
JavaScript
Listening to theURL
And according toURL
To render the new page;
How can you apply URLs and rendered pages? The front-end routing
- Front-end routing is maintained
URL
And the rendering page mapping relationship; - The route can vary according to the
URL
And 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
URL
的hash
This is the anchor point (#
), essentially changewindow.location
的href
Properties;- We can do this by direct assignment
location.hash
To 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:
Angular
的ngRouter
React
的ReactRouter
Vue
的vue-router
Since version 4 of the React Router, routes are no longer managed in a single package:
react-router
是router
The core part of the code;react-router-dom
It’s for the browser;react-router-native
It’s for native applications;
The latest React Router version is V5:
- In fact
v4
The version andv5
There is not much difference between the versions of the
Install the react – the router:
- The installation
react-router-dom
It will automatically help us install itreact-router
Rely 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:
BrowserRouter
或 HashRouter
Router
Contains listening for path changes and passes the corresponding path to child components.BrowserRouter
Use the History pattern;HashRouter
usehash
Mode;
The Link and NavLink:
- The usual path of the jump is used
Link
Component will eventually be rendered asa
Elements; NavLink
Is in theLink
Some style attributes are added on top of this (later);to
Properties:Link
Set the path to which to jump.
The Route:
Route
For path matching;path
Property: used to set the path to match;component
Property: 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 first
NavLink
To add onexact
Properties;
<NavLink exact to="/" activeStyle={{ color: 'red' }}>
首页
</NavLink>
Default ActiveClassName:
- In fact, when the default match is successful,
NavLink
I’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
/about
And at the same time that the path is matched,/:userid
It was also matched, and the last oneNoMatch
Components 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 time
Switch
Let’s take all of thisRoute
Carries 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 to
User
Interface; - But in the
User
The interface has oneisLogin
To 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 directly
history
,location
,match
Objects, 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 available
react-router
Advanced components providedwithRouter
Add 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;
search
Passing parameters;to
The incoming object
Dynamic routing
The concept of dynamic routing refers to the fact that paths in a route are not fixed:
- Such as
/detail
thepath
Corresponding to a componentDetail
; - If we were to
path
在Route
When I match, I write/detail/:id
, then/detail/abc
,/detail/123
Can be matched to thatRoute
And 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 through
match
Fetch in an objectid
; - We’re not using it here
withRouter
The reason is thatDetail
It 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 jump
query
Parameters;
<NavLink to="/detail2? </NavLink> <Switch> <Route path="/detail2" component={detail2}/> </Switch>
How do I get that in Detail2?
Detail2
In is needed inlocation
To derivesearch
;
Note:this
search
It’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 time
react-router-config
To 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 to
this.props.route
Properties; - the
route
Property 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!