0604嵌套路由与路由传参-react路由-react

1 嵌套路由

1.1 使用

示例效果如下图1.1-1所示:

在这里插入图片描述

该示例代码其他部分和上一篇相同,这里主要讲解下嵌套路由的使用。

分析:home组件中嵌套了News和Message两个路由组件。

  • 创建News组件

    • 在原项目结构Home文件夹下创建News/index.jsx

    • 源代码1.1-1如下所示

      import React, { Component } from 'react'
      
      export default class News extends Component {
        render() {
          return (
            <ul>
            <li>news001</li>
            <li>news002</li>
            <li>news003</li>
          </ul>
          )
        }
      }
      
  • 创建Message组件

    • Home文件夹下创建Message/index.jsx

    • 源代码1.1-2如下图所示

      import React, { Component } from 'react'
      
      export default class Message extends Component {
        render() {
          return (
            <div>
              <ul>
                <li>
                  <a href="/message1">message001</a>&nbsp;&nbsp;
                </li>
                <li>
                  <a href="/message2">message002</a>&nbsp;&nbsp;
                </li>
                <li>
                  <a href="/message/3">message003</a>&nbsp;&nbsp;
                </li>
              </ul>
            </div>
          )
        }
      }
      
  • Home/jsx添加导航链接和注册路由

    • 源代码1.1-3如下所示:

      import React, { Component } from 'react'
      import { Route, Switch, Redirect } from 'react-router-dom';
      import MyNavLink from '../../components/MyNavLink'
      import Message from './Message';
      import News from './News'
      
      export default class Home extends Component {
        render() {
          return (
            <div>
              <h3>我是Home的内容</h3>
              <div>
                <ul className="nav nav-tabs">
                  <li>
                    <MyNavLink to="/home/news">News</MyNavLink>
                  </li>
                  <li>
                    <MyNavLink to="/home/message">Message</MyNavLink>
                  </li>
                </ul>
              </div>
              {/* 注册路由 */}
              <Switch>
                <Route path="/home/news" component={News} />
                <Route path="/home/message" component={Message} />
                <Redirect to="/home/news" />
              </Switch>
            </div>
          )
        }
      }
      

启动项目,完成嵌套路由的使用。

  • 分析路由匹配原理
    • 首先react完成App.jsx中路由注册
    • 当点击News时,对应路径"/home/news"开始按照路由注册顺序开始匹配。
      • 优先模糊匹配"/home",展示Home组件。
      • 继续匹配Home组件中路径"/home/news",展示News组件。

1.2 总结

  • 注册路由时要写上父路由的path值;
  • 路由匹配是按照注册路由的顺序进行的。

2 路由传参

2.1 示例准备

示例效果,点击消息,展示对应的消息内容,如下图2.1-1所示:

在这里插入图片描述

示例其他代码同上,这里只写对应的消息部分。

  • 简单分析

    • 当前为二级路由下导航链接,点击链接,展示消息详情,即为三级路由。
    • 消息详情结构一致,封装为路由组件Detail。
    • Message组件下消息结构一样,内容不同,在state中写数据,遍历动态生成。
  • Detail组件代码2.1-1如下所示:

    import React, { Component } from 'react'
    
    export default class Detail extends Component {
      render() {
        return (
          <ul>
            <li>ID:xxx</li>
            <li>TITLE:xxx</li>
            <li>CONTENT:xxx</li>
          </ul>
        )
      }
    }
    
  • Messge组件代码2.1-2如下所示:

    import React, { Component } from 'react'
    import { Link, Route } from 'react-router-dom'
    import Detail from './Detail'
    
    export default class Message extends Component {
      state = {
        messArr : [
          { id: '01', title: '消息1' },
          { id: '02', title: '消息2' },
          { id: '03', title: '消息3' },
        ]
      }
      render() {
        const { messArr } = this.state
        return (
          <div>
            <ul>
              {
                messArr.map((msg) => {
                  return (
                    <li key={msg.id}>
                      <Link to="/home/message/detail">{msg.title}</Link>&nbsp;&nbsp;
                    </li>
                  )
                })
              }
            </ul>
            <hr />
            <Route path="/home/message/detail" component={Detail}></Route>
          </div>
        )
      }
    }
    

如果想要实现点击不同消息链接,展示不同的消息内容,需要通过路由传递参数。下面我们详细讲解三种路由传参方式,并做总结和比较。

2.1 传递params参数

  • 第一步:路由链接向路由组件传递params参数

    {/* 格式:/}
    <Link to="/path1/path2/.../pathn/参数1/参数2/.../参数n"></Link>
    {/* 示例:/}
    {/* 向路由组件传递params参数 */}
    <Link to={`/home/message/detail/${msg.id}/${msg.title}`}>{msg.title}</Link>&nbsp;&nbsp;
    
  • 第二步:路由组件声明接收params参数

    {/* 格式 */}
    <Route path="/path1/path2/.../pathn/:参数1/:参数2/.../:参数n" component={组件}></Route>
    {/* 示例 */}
    {/* 声明接收params参数 */}
    <Route path="/home/message/detail/:id/:title" component={Detail}></Route>
    
  • 第三步:组件获取参数

    // 组件内 this.props.match.params 即为react封装好的params对象
    const {id, titel} = this.props.match.params
    

Detail组件index.jsx组件获取和展示参数如下所示源代码2.1-1如下所示:

import React, { Component } from 'react'
const data = [
  {id: 1, content: '学习 Java'},
  {id: 2, content: '学习 Python'},
  {id: 3, content: '学习 React'},
]

export default class Detail extends Component {
  render() {
    // console.log(this.props);
    let {id, title} = this.props.match.params
    id = id - 0
    const detail = data.find((detail) => {
       return detail.id === id
    })  
    return (
      <ul>
        <li>ID: {id}</li>
        <li>TITLE: {title}</li>
        <li>CONTENT: {detail.content}</li>
      </ul>
    )
  }
}

2.2 传递search参数

  • 第一步:路由链接向路由组件传递search参数

    {/* 格式:/}
    <Link to="/path1/path2/.../pathn/?参数1=值1&参数2=值2&...&参数n=值n"></Link>
    {/* 示例:/}
    {/* 向路由组件传递params参数 */}
    <Link to={`/home/message/detail/?id=${msg.id}&title=${msg.title}`}>{msg.title}</Link>&nbsp;&nbsp;
    
  • 第二步:接受search参数无需声明

    {/*  */}
    <Route path="/path1/path2/.../pathn" component={组件}></Route>
    {/* 示例 */}
    {/* 声明接收params参数 */}
    <Route path="/home/message/detail" component={Detail}></Route>
    
  • 第三步:组件获取参数

    // 组件内 this.props.location.search 为接受的search字符串,形式:?参数1=值1&参数2=值2&...
    // 需要自己处理或者第三方库
    const {search} = this.props.location
    

Detail组件index.jsx组件获取和展示参数如下所示,其他同上源代码2.1-2如下所示:

let {id, title} = qs.parse(this.props.location.search, {ignoreQueryPrefix: true})

2.3 传递state参数

注:此state为组件state参数不是组件的state属性。

  • 第一步:路由链接向路由组件传递state参数

    {/* 格式:/}
    <Link to={{pathname: "/path1/path2/.../pathn, state: {参数1: 值1, 参数2: 值2, ...}}}></Link>
    {/* 示例:/}
    {/* 向路由组件传递state参数 */}
    <Link to={{pathname: '/home/message/detail', state: msg}}>{msg.title}</Link>
    
  • 第二步:接受search参数无需声明

    {/* 格式 */}
    <Route path="/path1/path2/.../pathn" component={组件}></Route>
    {/* 示例 */}
    {/* 无需声明接收state参数 */}
    <Route path="/home/message/detail" component={Detail}></Route>
    
  • 第三步:组件获取参数

    // 组件内 this.props.location.state 即为接受的state参数对象
    const {id, title} = this.props.location.state
    

Detail组件index.jsx组件获取和展示参数如下所示,其他同上源代码2.1-2如下所示:

// 接收state参数
let {id, title} = this.props.location.state

2.4 路由参数总结

  • 使用形式
  1. params参数传递
    • 路由链接传递参数:<Link to="/demo/test/4/aaa">测试</Link>
    • 路由组件声明加收参数:<Route path="/demo/test/:id/:title" component={Test} />
    • 组件接受参数:let {id, title} = this.props.match.params
  2. search参数传递
    • 路由链接传递参数:<Link to="/demo/test/?id=1&title=xxx">测试</Link>
    • 注册路由组件(无需声明):<Route path="/demo/test" component={Test} />
    • 组件接受参数:let {search} = this.props.locaiton,然后解析
  3. state参数
    • 路由链接传递参数:<Link to={{pathname: '/demo/test', state: {id: 1, title: 'xxx'}}}>测试</Link>
    • 注册路由组件(无需声明):<Route path="/demo/test" component={Test} />
    • 组件接受参数:let {id, title} = this.props.location.state
    • 注:刷新也可以保住参数*,因为路由器是BrowserRouter,react维护history;但是如果清空缓存,参数丢失。
  • 比较
    • params传参:路径携带参数;
    • search传参:路径携带参数,接受参数后需要另外解析;
    • state传参:适用于参数具有一定保密性需求,不希望对外暴露场景

结语

❓QQ:806797785

⭐️源代码仓库地址:https://github.com/gaogzhen/react-staging.git

参考:

[1]React视频教程[CP/OL].2020-12-15.p85-89.

[2]React官网[CP/OL].

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gaog2zh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值