React路由初始

一、SPA单页面

1、单页Web应用(单个html)

2、整个应用只有一个完整的页面

3、点击页面中的链接不会刷新页面,只会做页面的局部刷新

4、数据都需要通过ajax请求获取,并在前端异步展现

二、路由的理解

1、什么是路由

一个路由就是一个映射关系(key:value);key为路径,value可能就是function或component

2、路由的分类

1)后端路由:value是fuction,用来处理客户端提交的请求;

注册路由:router.get(path,function(req,res));

工作过程:当node接收到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据

2)前端路由:浏览器端路由,value是component,用于展示页面内容

注册路由:<Route path="test" component={Test}>

工作过程:当浏览器的path变为/test时,当前的路由组件就会变成Test组件

路由HISTORY有两种方式:History.createBrowserHistory(),直接使用H5推出的history身上的API;History.createHashHistory(),hash值(锚点)有历史记录,但是值的改变不会出发页面变化

3、react-router-dom的理解

react的一个插件库;专门用来实现一个SPA应用;基于react的下你项目基本都会用到此库。

1) Link、Route与BrowserRouter

javascript 复制代码
import { Link,BrowserRouter } from 'react-router-dom'


//在react中靠路由链接实现切换路由--编写路由链接
<BrowserRouter>
    <Link to="/about">关于</Link>
</BrowserRouter>
javascript 复制代码
import { Route,BrowserRouter } import 'react-router-dom'

//注册路由
<BrowserRouter>
    <Route path="/about" component={About}/>
</BrowserRouter>

浏览器地址栏为 https://xxx.xxx.xxx:xxxx/about

2)HashRouter

javascript 复制代码
import { Link,HashRouter } from 'react-router-dom'


<HashRouter>
    <Link to="/about">关于</Link>
</HashRouter>
javascript 复制代码
import { Route,HashRouter } import 'react-router-dom'


<HashRouter>
    <Route path="/about" component={About}/>
</HashRouter>

浏览器地址栏为 https://xxx.xxx.xxx:xxxx/#/about

注:由于Link与Route都需要BrowserRouter包裹,且不能在项目中多次出现<BrowserRouter>或<HashRouter>,我们在项目中的index.js里对<App>进行包裹

javascript 复制代码
import React from 'react'

import ReactDOM from 'react-dom'

import { BrowserRouter } from 'react-router-dom'

import App from './App

ReactDOM.render(
    <BrowserRouter>
        <App/>
    </BrowserRouter>,
    document.getElementById('root')
)

3)路由组件与一般组件

1.写法不同:

一般组件:<Demo />

路由组件:<Route path="/about" component={About}/>

2.存放的位置不同

一般组件:component

路由组件:pages

3.接收到的props不同

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

路由组件:接收到3个固定的属性 history、location、match

如果实现如图所示的效果:点击About或Home的话,路由会高亮。按照bootstript的写法

javascript 复制代码
<BrowserRouter>
    <Link to="/about" active>About</Link>
    <Link to="/home">Home</Link>
</BrowserRouter>

需要在Link里添加active

javascript 复制代码
import { NavLink,BrowserRouter } from 'react-router-dom'

<BrowserRouter>
    <NavLink to="/about">About</NavLink>
    <NavLink to="/home">Home</NavLink>
</BrowserRouter>

使用NavLink的话,react就会默认添加了active,点击路由,被激活的路由自然而然加了背景色,此外如果觉得默认的样式不好看的话,可以在NavLink加"activeClassName"给路由添加激活状态的样式,这里的激活状态样式应该加高权重。

javascript 复制代码
import { React,{Component}} from 'react'
import { NavLink,BrowserRouter } from 'react-router-dom'

export default MyNavLink extends Component {
    render(){
        coonst { to,title } = this.props
        return (
            <BrowserRouter>
                <NavLink to={to}>{title}</NavLink>
            </BrowserRouter>
        )
    }
}
javascript 复制代码
<MyNavLink to="/ablut" title="关于"></MyNavLink>

此外,如果给MyNavLink传递的过多,可以直接用{...this.props}展开

javascript 复制代码
import { React,{Component}} from 'react'
import { NavLink,BrowserRouter } from 'react-router-dom'

export default MyNavLink extends Component {
    render(){
        coonst { title } = this.props
        return (
            <BrowserRouter>
                <NavLink {...this.props}>{title}</NavLink>
            </BrowserRouter>
        )
    }
}

另外如果我想以"<MyNavLink to="/ablut">关于</MyNavLink>"的形式呢?这也是可以封装的

上个代码示例中,打印this.props的话,会有个children属性

javascript 复制代码
import { React,{Component}} from 'react'
import { NavLink,BrowserRouter } from 'react-router-dom'

export default MyNavLink extends Component {
    render(){
        console.log(this.props)
        return (
            <BrowserRouter>
                <NavLink {...this.props} />
            </BrowserRouter>
        )
    }
}

6) Switch的使用

javascript 复制代码
import { Route,BrowserRouter } import 'react-router-dom'

<BrowserRouter>
     <Route path="/about" component={About}/>
     <Route path="/about" component={Home}/>
</BrowserRouter>

以上的情况:如果路由是"/about"的话,组件About和Home都会显示出来,也就是说路由在匹配到路由时会继续往下进行匹配,如果路由多的话,不仅会耗性能还会出现意想不到的内容下是出来,所以我们可以使用Switch进行包裹,当匹配到适合的路由就停止往下继续匹配

javascript 复制代码
import { Route,BrowserRouter,Switch } import 'react-router-dom'

<BrowserRouter>
    <Switch>
         <Route path="/about" component={About}/>
         <Route path="/about" component={Home}/>
    </Switch>
</BrowserRouter>

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

7)样式丢失问题

项目启动的本地路径http://XXX.XXX.XXX.XXX:XXXX,这是内置devServe服务器的请求地址,当后面跟的路径是在路由中不存在时(多级路由),react会默认展示为public文件下的index.html页面。

1、public/index.html中引入样式时,不写 ./ 要写 /

2、public/index.html中引入样式的改为"%PUBLIC_URL%/css"

2、在根组件使用HashRouter包裹

8)路由的模糊匹配

javascript 复制代码
import { Route,BrowserRouter,Switch } import 'react-router-dom'

<BrowserRouter>
    <Switch>
         <Route path="/home" component={Home}/>  //home页面
         <Route path="/home/a/b" component={Home}/>  //没有a文件b页面,依旧显示home
         <Route path="/a/home/b" component={Home}/>  //没有a文件b页面,什么也不显示
          //以上就是路由的模糊匹配,从左到右依次匹配,有就显示,如果开头就没有,就不继续往下进行匹        配

        //相反
        <Route exact={true} path="/home" component={Home}/> //严格匹配
        <Route exact path="/home" component={Home}/>  //严格匹配
    </Switch>
</BrowserRouter>

1.默认使用的是模糊匹配,输入的路径必须包含要匹配的路径,且顺序要一致

2.开启严格模式<Route exact={true} path="/home" component={Home}/>

3.严格匹配不要随便开启,需要时再开,有些时候开启会导致无法继续匹配二级路由

9)Redirct重定向

javascript 复制代码
import { Route,BrowserRouter,Switch,Redirct } import 'react-router-dom'

<BrowserRouter>
    <Switch>
        <Route path="/home" component={Home}/>
        <Route path="/about" component={About}/>
        <Redirct path="/home" />  //当路由没有/home、没有/about,页面会直接显示home页面。
    </Switch>
</BrowserRouter>

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

10)嵌套路由

javascript 复制代码
import { Route,BrowserRouter,Switch } import 'react-router-dom'

<BrowserRouter>
    <Switch>
         <Route path="/about/a" component={About}/>
         <Route exact path="/home/about" component={Home}/> //  路由是/home,页面是不会展示的
         <Redirct path="/home/b">
    </Switch>
</BrowserRouter>

1.注册子路由时要写上父路由的path值

2.路由的匹配是按照路由的顺序进行的

三、路由传参

1、向路由组件传递params参数

javascript 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    //向路由组件传递params参数 
    <Link to="{`/about/${参数}`}" active>About</Link>


    //声明接收params参数
    <Route path="/about:params" component={About} />

    // <Link to="{`/about/${参数1}/{参数二}`}" active>About</Link>
    //<Route path="/about/:params1/:params2"component={About} />
</BrowserRouter>

在About组件中打印 this.props

this.props.match.params就是你传递的路由参数集合。

* 路由链接(携带参数) <Link to="/about/18">About</Link>

* 注册路由(声明接收) <Route path="/about/:params1" component={About} />

* 接收参数 const { params1 } = this.props.match.params

2、向路由组件传递search参数

java 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    //向路由组件传递search参数 
    <Link to="{`/about/?params=${this.state.params1}`}">About</Link>

    //search无需声明,正常注册
    <Route path="/about" component={About} />
</BrowserRouter>

在About组件中,打印 this.props

开发中,参数最好是对象的形式。

querystring

React内置

javascript 复制代码
import qs from "querystring"

let obj = { name:'a',age:18 } 
qs.stringify(obj) //name=a&age=18


let str = 'name=a&age=18'
qs.parse(str) //{ name:'a',age:18 } 

3、向路由组件传递state参数

java 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    //向路由组件传递state参数 
    <Link to="{`/about`,state:{ name:this.state.name,age:this.state.age }}">About</Link>

    <Route path="/about" component={About} />
</BrowserRouter>

在About组件中,打印 this.props

4、push和replace

路由默认是push模式,也就是说路由的变换在浏览器中是有记录的,可以正常执行浏览的回退操作。而replace是替换路由,在浏览器中是没有记录的,

javascript 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    <Link replace={true} to="{`/about`,state:{ name:this.state.name,age:this.state.age }}">About</Link>

    //    <Link replace={true} to="{`/about`,state:{ name:this.state.name,age:this.state.age }}">About</Link>

    <Route path="/about" component={About} />
</BrowserRouter>
相关推荐
恋猫de小郭1 小时前
ADB Wi-Fi 2.0 ,Android 17 把无线调试的连接链路重新做了一遍
android·前端·flutter
问心无愧05131 小时前
ctf show web 178
前端·笔记
岁岁种桃花儿1 小时前
Vue组件化编程第二篇:非单位件组件
前端·javascript·vue.js
晓得迷路了1 小时前
栗子前端技术周刊第 146 期 - React 19.3、jQuery 1.0 20 周年、Bun 1.4.2...
前端·javascript·react.js
雪芽蓝域zzs1 小时前
第四十四节:封装通用表格多选、批量操作组合式函数
前端·javascript·vue.js
那年窗外下的雪.1 小时前
AIDC 学习日志|第 25 天|设备输出反推、MAC Flapping 与 EAD 撤销
前端·网络·git·学习·macos
IT_陈寒1 小时前
Vite的HMR怎么突然罢工了?原来是我漏了这个配置
前端·人工智能·后端
柳杉2 小时前
从调研到闭环,我用 GPT-Image-2.5 和 GPT-6 Astra 把智慧厂房 3D 大屏这条链路走完了
前端·ai编程·数据可视化
芳心粽伙饭2 小时前
CSS第四章 布局
前端·css·html