A detailed introduction to React routing

routing

For a single page web application (single page web application, SPA), the entire application has only one complete page. Clicking a link in the page will not refresh the page, but only a partial update of the page. All data needs to be obtained through ajax requests and displayed asynchronously on the front end.

A route is a mapping relationship (key:value), the key is a path, and the value may be a function or a component.
Backend routing:

  1. Understanding: value is a function, which is used to process the request submitted by the client.
  2. Register routing: router.get(path, function(req, res))
  3. Working process: When node receives a request, it finds the matching route according to the request path, calls the function in the route to process the request, and returns the response data

Front-end routing:

  1. Browser-side routing, value is component, used to display page content.
  2. Register route:<Route path="/test" component={Test}>
  3. Working process: When the path of the browser changes to /test, the current routing component will become a Test component

React Routing

react-router-dom is a plug-in library of react, which is specially used to implement a SPA application. React-based projects will basically use this library. Download using command npm i react-router-dom.
Related API: built-in components:

1.	<BrowserRouter>
2.	<HashRouter>
3.	<Route>
4.	<Redirect>
5.	<Link>
6.	<NavLink>
7.	<Switch>

Changes in the new version of v6

In the use of react-router and react-router-dom in version 6, there is a little difference from the old version.

  • Switch becomes Routes. All Route components should be wrapped by Routes. Using Route outside the Routes component will report an error.
  • Redirect becomes Navigate, and the Navigate component cannot be written in Routes, otherwise an error will be reported, that is, the Routes component only accepts Route as its subcomponent.
  • v6 removed WithRouter and added some new hooks.

Related Articles 1Related
Articles 2

Basic use of routing

//App.jsx

import React, {
    
     Component } from 'react'
import {
    
    Link,Route} from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
export default class App extends Component {
    
    
	render() {
    
    
		return (
			<div>
				{
    
    /* 原生html中,靠<a>跳转不同的页面 */}
				{
    
    /* <a className="list-group-item" href="./about.html">About</a>
				<a className="list-group-item active" href="./home.html">Home</a> */}
				
				
				{
    
    /* 在React中靠路由链接实现切换组件--编写路由链接 */}
				<Link to="/about">About</Link>
				<Link to="/home">Home</Link>
				
				{
    
    /* 注册路由,进行路径的匹配 */}
				<Route path="/about" component={
    
    About}/>
				<Route path="/home" component={
    
    Home}/>
			</div>
		)
	}
}
//index.js
import React from 'react'
import ReactDOM from 'react-dom'
import {
    
    BrowserRouter} from 'react-router-dom'
import App from './App'
//<App>的最外侧包裹了一个<BrowserRouter>或<HashRouter>
ReactDOM.render(
	<BrowserRouter>
		<App/>
	</BrowserRouter>,
	document.getElementById('root')
)

insert image description here

Routing Components vs Generic Components

1. Different writing methods:
general components: <Demo/>
routing components: <Route path="/demo" component={Demo}/>
2. Different storage locations:
general components: components/
routing components: pages/
3. The received props are different:
general components: what is passed when writing component tags, you can receive them What
Routing Component: Receives three fixed properties

history:
			go: ƒ go(n)
			goBack: ƒ goBack()
			goForward: ƒ goForward()
			push: ƒ push(path, state)
			replace: ƒ replace(path, state)
location:
			pathname: "/about"
			search: ""
			state: undefined
match:
			params: {
    
    }
			path: "/about"
			url: "/about"

NavLink和Switch

NavLink :
<Link to="/about">About</Link>an upgraded version:
<NavLink activeClassName="zagiee" to="/about">About</NavLink>you can pass one more attribute, activeClassName, click on the current one to add a class name, add some styles, shi.

Switch :
Usually, path and component have a one-to-one correspondence. Switch can improve routing matching efficiency (single matching).

When there are multiple paths that are the same, and the home is matched without the Switch package, the first match will continue to match, and the second will also match, so that both are displayed, and the first one is matched after being wrapped. After one, it will not match down, so only the first one will be displayed.

{
    
    /* 注册路由 */}
<Switch>
	<Route path="/about" component={
    
    About}/>
	<Route path="/home" component={
    
    Home}/>
	<Route path="/home" component={
    
    Test}/>
</Switch>

Solve the problem that the multi-level path refresh page style is lost

When the path is multi-level, refreshing the page may cause style loss.

<Link to="/zagiee/home">Home</Link>
<Route path="/zagiee/home" component={
    
    Home}/>

Solution:
1. Do not write ./write/ (commonly used) when introducing styles in public/index.html
2. Do not write ./write %PUBLIC_URL% when introducing styles in public/index.html (commonly used)
3. Use HashRouter ( uncommonly used)

Strict and fuzzy matching of routes

1. By default, fuzzy matching is used (the input path to must contain the path path to be matched, and the order must be consistent).
2. Turn on strict matching: <Route exact={true} path="/about" component={About}/>, abbreviation: <Route exact path="/about" component={About}/>
3. Do not turn on strict matching casually, you need to turn it on again, sometimes turning it on will make it impossible to continue to match the secondary route
4. Generally, this route with path="/" will generally add exact, otherwise it will would also match '/home' making this route useless.
In addition, do not add the exact attribute to the nested route. If the parent route is added, the child route below it will not take effect, because the outer layer is forced to match

Pass parameters to routing components

1. params parameter
routing link (carrying parameters): <Link to='/demo/test/tom/18'}>详情</Link>
registering routing (declaration receiving): <Route path="/demo/test/:name/:age" component={Test}/>
receiving parameters: this.props.match.params
2. search parameter
routing link (carrying parameters): <Link to='/demo/test?name=tom&age=18'}>详情</Link>
registering routing (no need to declare, normal registration is enough): <Route path="/demo/test" component={Test}/>
receiving parameters this.props.location.search
: Remarks: get The search obtained is a urlencoded encoded string, which needs to be parsed with the help of querystring
3. State parameters
Routing link (carrying parameters): <Link to={ {pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
register routing (no need to declare, just register normally): <Route path="/demo/test" component={Test}/>
receiving parameters: this.props.location.state
Remarks: Refresh can also retain parameters, the first two One is fine too.

//Message/index.jsx

state = {
    
    
		messageArr:[
			{
    
    id:'01',title:'消息1'},
			{
    
    id:'02',title:'消息2'},
			{
    
    id:'03',title:'消息3'},
		]
	}
render() {
    
    
	const {
    
    messageArr} = this.state
	return (
		<div>
			<ul>
				{
    
    
					messageArr.map((msgObj)=>{
    
    
						return (
							<li key={
    
    msgObj.id}>

								{
    
    /* 向路由组件传递params参数 */}
								{
    
    /* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}

								{
    
    /* 向路由组件传递search参数 */}
								{
    
    /* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}

								{
    
    /* 向路由组件传递state参数,双括号是对象,单括号是js模板字符串,前两种也能写成对象形式 */}
								<Link to={
    
    {
    
    pathname:'/home/message/detail',state:{
    
    id:msgObj.id,title:msgObj.title}}}>{
    
    msgObj.title}</Link>

							</li>
						)
					})
				}
			</ul>			
			<hr/>
			{
    
    /* 声明接收params参数 */}
			{
    
    /* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}
			
			{
    
    /* search参数无需声明接收,正常注册路由即可 */}
			{
    
    /* <Route path="/home/message/detail" component={Detail}/> */}
			
			{
    
    /* state参数无需声明接收,正常注册路由即可 */}
			<Route path="/home/message/detail" component={
    
    Detail}/>
		</div>
//Message/Detail/index.jsx
import React, {
    
     Component } from 'react'
// import qs from 'qs'

const DetailData = [
	{
    
    id:'01',content:'你好,中国'},
	{
    
    id:'02',content:'你好,尚硅谷'},
	{
    
    id:'03',content:'你好,未来的自己'}
]
export default class Detail extends Component {
    
    
	render() {
    
    
		console.log(this.props);

		// 接收params参数
		// const {id,title} = this.props.match.params 

		// 接收search参数
		// const {search} = this.props.location
		// const {id,title} = qs.parse(search.slice(1))

		// 接收state参数,加 || {}是为了防止报错,有值就用,没值就undefined
		const {
    
    id,title} = this.props.location.state || {
    
    }

		const findResult = DetailData.find((detailObj)=>{
    
    
			return detailObj.id === id
		}) || {
    
    }
		return (
			<ul>
				<li>ID:{
    
    id}</li>
				<li>TITLE:{
    
    title}</li>
				<li>CONTENT:{
    
    findResult.content}</li>
			</ul>
		)
	}
}

push and replace

push: What you see is the address at the top of the stack. Clicking back will pop out of the stack and return to the previous page (message).
insert image description here

Replace is to use it to replace the top address of the stack, and the rollback will return to news.

<Link replace to={
    
    `/home/message/detail/?id=${
      
      msgObj.id}&title=${
      
      msgObj.title}`}>{
    
    msgObj.title}</Link>

insert image description here

Programmatic Routing Navigation

Use the API on this.prosp.history object to jump, forward, and backward the operation route

this.prosp.history.push()
this.prosp.history.replace()
this.prosp.history.goBack()
this.prosp.history.goForward()
this.prosp.history.go()
export default class Message extends Component {
    
    
	state = {
    
    
		messageArr:[
			{
    
    id:'01',title:'消息1'},
			{
    
    id:'02',title:'消息2'},
			{
    
    id:'03',title:'消息3'},
		]
	}

	replaceShow = (id,title)=>{
    
    
		//replace跳转+携带params参数
		//this.props.history.replace(`/home/message/detail/${id}/${title}`)

		//replace跳转+携带search参数
		// this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)

		//replace跳转+携带state参数
		this.props.history.replace(`/home/message/detail`,{
    
    id,title})
	}

	pushShow = (id,title)=>{
    
    
		//push跳转+携带params参数
		// this.props.history.push(`/home/message/detail/${id}/${title}`)

		//push跳转+携带search参数
		// this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)

		//push跳转+携带state参数
		this.props.history.push(`/home/message/detail`,{
    
    id,title})
		
	}

	back = ()=>{
    
    
		this.props.history.goBack()
	}

	forward = ()=>{
    
    
		this.props.history.goForward()
	}

	go = ()=>{
    
    
		this.props.history.go(-2)
	}

	render() {
    
    
		const {
    
    messageArr} = this.state
		return (
			<div>
				<ul>
					{
    
    
						messageArr.map((msgObj)=>{
    
    
							return (
								<li key={
    
    msgObj.id}>

									{
    
    /* 向路由组件传递params参数 */}
									{
    
    /* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}

									{
    
    /* 向路由组件传递search参数 */}
									{
    
    /* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}

									{
    
    /* 向路由组件传递state参数 */}
									<Link to={
    
    {
    
    pathname:'/home/message/detail',state:{
    
    id:msgObj.id,title:msgObj.title}}}>{
    
    msgObj.title}</Link>

									&nbsp;<button onClick={
    
    ()=> this.pushShow(msgObj.id,msgObj.title)}>push查看</button>
									&nbsp;<button onClick={
    
    ()=> this.replaceShow(msgObj.id,msgObj.title)}>replace查看</button>
								</li>
							)
						})
					}
				</ul>
				<hr/>
				{
    
    /* 声明接收params参数 */}
				{
    
    /* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}

				{
    
    /* search参数无需声明接收,正常注册路由即可 */}
				{
    
    /* <Route path="/home/message/detail" component={Detail}/> */}

				{
    
    /* state参数无需声明接收,正常注册路由即可 */}
				<Route path="/home/message/detail" component={
    
    Detail}/>

				<button onClick={
    
    this.back}>回退</button>&nbsp;
				<button onClick={
    
    this.forward}>前进</button>&nbsp;
				<button onClick={
    
    this.go}>go</button>

			</div>
		)
	}
}

withRouter

withRouter can process general components, so that general components have the unique API of routing components, and the return value of withRouter is a new component.

//一般组件Header/index.jsx
import {
    
    withRouter} from 'react-router-dom'
class Header extends Component {
    
    
	……
}
export default withRouter(Header)

The difference between BrowserRouter and HashRouter

1. The underlying principle is different.
BrowserRouter uses the H5 history API, which is not compatible with IE9 and below.
HashRouter uses the hash value of the URL.
2. The path expression is different.
There is no # in the path of BrowserRouter, for example: localhost:3000/demo/test
The path of HashRouter contains #, for example: localhost:3000/#/demo/test
3. The impact on the route state parameter after refreshing
(1).BrowserRouter has no effect, because the state is stored in the history object.
(2). After the HashRouter is refreshed, the routing state parameter will be lost! ! !
4. Note: HashRouter can be used to solve some path error related problems.

Guess you like

Origin blog.csdn.net/zag666/article/details/129941161