react-路由router

129 阅读3分钟

下载

pnpm add react-router-dom@5  //版本5
pnpm add react-router-dom  //版本6

路由链接

<Link to="/about">About</Link>  // 跳转about路由的组件

注册路由

<Route path="/about" component={About} />  // 匹配的路径path 匹配的组件component

路由模式

通过在app.js中书写路由包裹组件,保证每个组件包裹在同一路由模式下

<BrowserRouter><App /></BrowserRouter>  // history模式
<HashRouter><App /></HashRouter>  // hash模式

路由组件和一般组件

一般组件存放在components下,路由组件存放在pages下
一般组件直接在页面使用渲染,路由组件通过Router标签的component属性使用
一般组件接收传递的props值,路由组件接收路由器的属性值

NavLink

通过activeClassName属性设置追加的选中类
<NavLink activeClassName="activeClass" to="/about">About</NavLink>  
// NavLink封装成一个组件

// 调用
<MyNavLink to="/about">About</MyNavLink>

// 组件  通过解构赋值的方法将参数传递给NavLink
 <NavLink activeClassName="activeClass" className="list-group-item" {...this.props} />

多级路由样式丢失

当路由为多级路由时,会出现刷新样式丢失的情况,将路由当做请求地址,造成找不到资源的情况
解决方法:

  • public样式引用路径使用“/css/xxx.css”
  • public样式引用路径使用“%PUBLIC_URL%/css/xxx.css”,不全路径
  • public样式引用路径使用“./css/xxx.css”,使用HashRouter模式,使切换路由不会请求服务器,hash值改变,页面变化

模糊匹配和精准匹配

  • 模糊匹配

默认匹配方式

<Link to="/about/a/b">About</Link> //会匹配到About组件
<Route path="/about" component={About} />
  • 精准匹配

使用exact开启精准匹配

<Link to="/about/a/b">About</Link>
<Route exact path="/about/a/b" component={About} />  

// 只有路径path和Link跳转to保持一致时,才会匹配到About组件

Redirect

当注册路由没有匹配的路由时,进行Redirect重定向

<Redirect to="/about" />

嵌套路由

当需要嵌套路由时,需要将路由以写全的方式形成多级路由,进行路由的匹配

<MyNavLink to="/home/news">News</MyNavLink>
<Route path="/home/news" component={News} />

路由传参

// 父组件
<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>
            </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>

// 子组件
import React, { Component } from 'react'
import qs from 'querystring-es3'  // webpack5之前使用querystring无需安装,webpack5之后使用querystring-es3需要安装

const detailData = [
    { id: '01', content: '内容1' },
    { id: '02', content: '内容2' },
    { id: '03', content: '内容3' }
]
export default class Detail extends Component {
    render() {
        // 接收params参数
        const { id, title } = this.props.match.params
        // 接收search参数
        const { search } = this.props.location
        const { id, title } = qs.parse(search.slice(1))
        // 接受state参数
        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

向栈中存入一个路由记录,保存历史路由

replace

替换当前路由

编程式路由

this.props.history.replace()

this.props.history.push()

this.props.history.goBack()

this.props.history.goForward()

this.props.history.go()

withRouter

将一般组件进行加工,使一般组件具有路由组件api
返回加工后的新组件

在React中,使用withRouter高阶组件可以让你在组件中访问路由信息,例如当前路由的路径、查询参数等。这样你就可以根据路由信息来执行相应的操作,比如根据路径改变导航栏的当前选项等。

要使用withRouter,你需要先安装react-router-dom库。安装完成后,可以通过以下步骤使用withRouter

  1. 在你的组件中导入withRouter
import withRouter from 'react-router-dom/withRouter';
  1. 将你的组件包装在withRouter函数中:
const MyComponent = withRouter(({ match, location }) => {
  // 在这里访问路由信息
  const path = match.path;
  const query = match.url.query;
  // ...
});

现在你的组件就可以访问路由信息了。你可以使用match属性来访问当前路由的信息,包括路径、查询参数等。还可以使用location属性来访问当前的URL信息,例如路径和查询参数。

注意,withRouter会将路由信息作为props传递给组件,因此你可以在组件中使用这些props来访问路由信息。

browserRouter和hashRouter

底层原理不同:
browserRouter使用的是history API,hashRouter使用的是url的hash值

表现形式不同:
hashRouter的url带有#的哈希值

刷新后starte参数影响:
browerRouter没有影响,state保存在history中
hashRouter刷新会导致state参数丢失