React----react-router(一)基础讲解

本文详细介绍了React Router的基础概念,包括路由组件与普通组件的区别,BrowserRouter与HashRouter的比较,以及如何使用NavLink、Redirect和Switch。还涵盖了嵌套路由、参数传递的方法,并提供了实际代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 路由简介

1. 什么是路由:

路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程.
一个路由就是一个映射关系(key:value),key为路径, value可能是function或component

2. React Router

React Router 是完整的 React 路由解决方案
React Router 保持 UI 与 URL 同步。它拥有简单的 API 与强大的功能例如代码缓冲加载、动态路由匹配、以及建立正确的位置过渡处理。你第一个念头想到的应该是 URL,而不是事后再想起。

react-router-dom:
1.react的一个插件库。
2.专门用来实现一个SPA应用。
3.基于react的项目基本都会用到此库。

二. 路由组件与一般组件区别:

1.写法不同

​ 一般组件:<Demo/>

​ 路由组件:<Route path="/demo" component={Demo}/>

2.存放位置不同

​ 一般组件:components

路由组件:pages

3.接收到的props不同

​ 一般组件:写组件标签时传递了什么,就能收到什么

​ 路由组件:接收到三个固定的属性

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"

三. React Router 基本使用

准备:
1.下载react-router-dom: npm install --save react-router-dom
2.引入bootstrap.css: <link rel="stylesheet" href="/css/bootstrap.css">
使用:
1.明确好界面中的导航区、展示区
​ 2.导航区用Link标签 <Link to="/xxxxx">Demo</Link>
3.展示区写Route标签进行路径的匹配 <Route path='/xxxx' component={Demo}/>
​4.的最外侧包裹了一个<BrowserRouter><HashRouter>

示例:
App.js:

import {Route,Link,withRouter} from 'react-router-dom'
import Home from './component/Home'
import About from './component/About'
function App(props) {
  return (
    <div>
      <h1>Route</h1>
      {/* Link 没有办法动态切换active样式 */}
        <Link to="/home">Home</Link>
        <br/>
        <Link to="about">About</Link> 
      <div>
        <Route path="/home" component={Home}></Route>
        <Route path="/about" component={About}></Route>
      </div>
    </div>
  )
}
export default withRouter(App);

index.js:入口文件中:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {BrowserRouter} from "react-router-dom"
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

四. react-router-dom相关API

1. BrowserRouter 和 HashRouter区别:

(1).底层原理不一样

BrowserRouter使用的是 H5 的history API,不兼容IE9及以下版本。

HashRouter使用的是URL的哈希值。

​ (2).path表现形式不一样:

BrowserRouter的路径中没有#,例如:localhost:3000/demo/test

HashRouter的路径包含#,例如:localhost:3000/#/demo/test

​ (3).刷新后对路由state参数的影响:

BrowserRouter没有任何影响,因为state保存在history对象中。

HashRouter刷新后会导致路由state参数的丢失!!!

​ (4).备注HashRouter可以用于解决一些路径错误相关的问题。

2.NavLink:

(1).NavLink和Link区别:

Link 没有办法动态切换active样式,
NavLink 可以动态切换样式, NavLink可以实现路由链接的高亮,通过activeClassName指定样式名

(2).使用:

import {Route,NavLink,withRouter} from 'react-router-dom'
import Home from './component/Home'
import About from './component/About'
function App(props) {
  return (
    <div>
      <h1>Route</h1>     
      <hr></hr>
        {/* NavLink 可以动态切换样式 */}
        <NavLink activeClassName="active" to="/home">Home</NavLink>
        <NavLink activeClassName="active" to="about">About</NavLink>
      <div>
        <Route path="/home" component={Home}></Route>
        <Route path="/about" component={About}></Route>
      </div>
    </div>
  )
}
export default withRouter(App);

3.Redirect:

(1).作用:一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由.

(2).使用:

import {Route,Redirect,NavLink,withRouter} from 'react-router-dom'
import Home from './component/Home'
import About from './component/About'
function App(props) {
  return (
    <div>
      <h1>Route</h1>
      <hr></hr>
        <NavLink activeClassName="active" to="/home">Home</NavLink>
        <NavLink activeClassName="active" to="about">About</NavLink>
        <Redirect to="/home"></Redirect>
      <div>
        <Route path="/home" component={Home}></Route>
        <Route path="/about" component={About}></Route>
      </div>
    </div>
  )
}
export default withRouter(App);

4. Switch:

(1). 作用:

通常情况下,path和component是一一对应的关系。
Switch可以提高路由匹配效率(单一匹配)。

(2).使用:

import React, { Component } from 'react'
import {Route,Switch,NavLink } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Header from './components/Header'
import MyNavLink from './components/MyNavLink'
import Test from './pages/Test'
export default class App extends Component {
	render() {
		return (
			<div>			
				<Header/>
				<hr/>	
				<NavLink activeClassName="active" to="/home">Home</NavLink>
        		<NavLink activeClassName="active" to="about">About</NavLink>					
				<div>
					{/* 注册路由 */}
					<Switch>
						<Route path="/about" component={About}/>
						<Route path="/home" component={Home}/>
						<Route path="/home" component={Test}/>
					</Switch>
				</div>
			</div>
		)
	}
}

五. 路由:

1. 嵌套路由:

1.注册子路由时要写上父路由的path值
2.路由的匹配是按照注册路由的顺序进行的

示例:

父路由:Home.js:

import React, { Component } from 'react'
import { NavLink,Route,Redirect } from 'react-router-dom'
import Childr from './child1'
import Child from './child2'
export default class Home extends Component {
    render() {
        return (
            <div>
                <h3>Home组件</h3>
                <NavLink to="/home/child1">一号</NavLink>
                &nbsp;
                <NavLink to="/home/child2">二号</NavLink>
                <Redirect to="/home/child1"></Redirect>
                <div>
                    <Route path="/home/child1" component={Childr}></Route>
                    <Route path="/home/child2" component={Child}></Route>
                </div>
            </div>
        )
    }
}

子路由:
child1

import React, { Component } from 'react'
import Transforme from "./transforme"
import { Link,Route} from 'react-router-dom'
export default class child1 extends Component {
    render() {
        return (
            <div>
                <h6>子路由111</h6>
            </div>
        )
    }
}

child2

import React, { Component } from 'react'
import Transforme from "./transforme"
import { Link,Route} from 'react-router-dom'
export default class child1 extends Component {
    render() {
        return (
            <div>
                <h6>子路由111</h6>
            </div>
        )
    }
}

2.路由传参:

​ (1). params参数

路由链接(携带参数)

<Link to='/demo/test/tom/18'}>详情</Link>

注册路由(声明接收)

<Route path="/demo/test/:name/:age" component={Test}/>

接收参数

this.props.match.params

父组件:

import React, { Component } from 'react'
import Transforme from "./transforme"
import { Link,Route} from 'react-router-dom'

export default class child1 extends Component {
    state = {
        DataTile:[
        {id:'01',title:'王俊凯'},
        {id:'02',title:'刘宇宁'},
        {id:'03',title:'毕雯珺'},
        ]
    }
    render() {
        const {DataTile} = this.state     
        return (
            <div>
                <h6>子路由111</h6>
                {DataTile.map((data)=>{
                    // console.log(data)                   
                    return (
                    	<li key={data.id}>
                        {/* params传参 */}
                      	<Link to={`/home/child1/transforme/${data.title}/${data.id}`}>{data.title}</Link>                                         
                    	</li>
                    )                    
            	})}              
                <div>
                    {/*params传参  */}
                   <Route path='/home/child1/transforme/:title/:id' component={Transforme}></Route> 
                </div> 
            </div>
        )
    }
}

子组件:

import React, { Component } from 'react'
const DataDetail = [
    {id:"01",age:21},
    {id:"02",age:31},
    {id:"03",age:22},
]
export default class transforme extends Component {
    render() {
        console.log(this.props)
        //params传参
        const {title,id}= this.props.match.params
        const findResult = DataDetail.find((detailObj)=>{
			return detailObj.id === id
		})
        return ( 
            <div>                
                <ul>
                    <li>id:{id}</li>
                    <li>name:{title}</li>
                    <li>age:{findResult.age}</li>
                </ul>
            </div>
        )
    }
}

​ (2).search参数

路由链接(携带参数)

<Link to='/demo/test?name=tom&age=18'}>详情</Link>

注册路由(无需声明,正常注册即可)

<Route path="/demo/test" component={Test}/>

接收参数

this.props.location.search

备注:获取到的search是urlencoded编码字符串,需要借助querystring解析 (npm i -save-dev query-string import qs from ‘query-string’)

在这里插入代码片

父组件:

import React, { Component } from 'react'
import Transforme from "./transforme"
import { Link,Route} from 'react-router-dom'

export default class child1 extends Component {
    state = {
        DataTile:[
        {id:'01',title:'王俊凯'},
        {id:'02',title:'刘宇宁'},
        {id:'03',title:'毕雯珺'},
        ]
    }
    render() {
        const {DataTile} = this.state       
        return (
           <div>
                <h6>子路由111</h6>
                {DataTile.map((data)=>{
                    // console.log(data)                   
                    return  (
                    	<li key={data.id}>
                    	{/* search传参 */}
                    	<Link to={`/home/child1/transforme?id=${data.id}&title=${data.title}`}>{data.title}</Link>                                          
                    	</li>
                    )
                    
                })}              
                <div>
                    {/* search传参,*/}
                    <Route path="/home/child1/transforme" component={Transforme}></Route>
                </div> 
            </div>
        )
    }
}

子组件:

import React, { Component } from 'react'
import qs from 'query-string'
const DataDetail = [
    {id:"01",age:21},
    {id:"02",age:31},
    {id:"03",age:22},
]
export default class transforme extends Component {
    render() {
        console.log(this.props)
        //search传参
        const data= qs.parse(this.props.location.search)
        const {title,id} = data
        console.log(data)
        const findResult = DataDetail.find((detailObj)=>{
			return detailObj.id === id
		})
        // console.log(Filter)
        return ( 
            <div>                
                <ul>
                    <li>id:{id}</li>
                    <li>name:{title}</li>
                    <li>age:{findResult.age}</li>
                </ul>
            </div>
        )
    }
}

​ (3).state参数

路由链接(携带参数)

<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>

注册路由(无需声明,正常注册即可)

<Route path="/demo/test" component={Test}/>

接收参数

this.props.location.state

备注:刷新也可以保留住参数
父组件:

import React, { Component } from 'react'
import Transforme from "./transforme"
import { Link,Route} from 'react-router-dom'

export default class child1 extends Component {
    state = {
        DataTile:[
        {id:'01',title:'王俊凯'},
        {id:'02',title:'刘宇宁'},
        {id:'03',title:'毕雯珺'},
        ]
    }
    render() {
        const {DataTile} = this.state       
        return (
            <div>
                <h6>子路由111</h6>
                {DataTile.map((data)=>{
                    // console.log(data)                   
                    return  (<li key={data.id}>
                        {/* state传参 */}
                        <Link to={{pathname:'/home/child1/transforme',state:{title:data.title,id:data.id}}}>{data.title}</Link>                     
                    </li>)
                    
                 })}              
                <div>
                    {/*state传参*/}
                    <Route path="/home/child1/transforme" component={Transforme}></Route>
                </div> 
            </div>
        )
    }
}

子组件:

import React, { Component } from 'react'
const DataDetail = [
    {id:"01",age:21},
    {id:"02",age:31},
    {id:"03",age:22},
]
export default class transforme extends Component {
    render() {
        console.log(this.props)
        //state传参
        const {title,id}= this.props.location.state
        const findResult = DataDetail.find((detailObj)=>{
			return detailObj.id === id
		})
        // console.log(Filter)
        return ( 
            <div>                
                <ul>
                    <li>id:{id}</li>
                    <li>name:{title}</li>
                    <li>age:{findResult.age}</li>
                </ul>
            </div>
        )
    }
}

总结:

真正学会 React 是一个漫长的过程.你会发现,它不是一个库,也不是一个框架,而是一个庞大的体系。想要发挥它的威力,整个技术栈都要配合它改造。你要学习一整套解决方案,从后端到前端,都是全新的做法。慢慢学吧各位~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值