React中路由的参数传递 - 路由的配置文件

Posted 学全栈的灌汤包

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React中路由的参数传递 - 路由的配置文件相关的知识,希望对你有一定的参考价值。

文章目录

路由的参数传递

传递参数有二种方式(需要注意的是, 这两种方式在Router6.x中都是提供的hook函数的API, 类组件需要通过高阶组件的方式使用):

动态路由的方式;

search传递参数(查询字符串);

方式一: 动态路由的概念指的是路由中的路径并不会固定:

比如/detail的path对应一个组件Detail;

如果我们将path在Route匹配时写成/detail/:id,那么 /detail/111、/detail/123都可以匹配到该Route,并且进行显示;

这个匹配规则,我们就称之为动态路由;

通常情况下,使用动态路由可以为路由传递参数。

  • 配置动态路由
render() 
  return (
    <div className='app'>
      <div className='header'>
        <Link to="detail/123">详情123</Link>
        <Link to="detail/321">详情321</Link>
        <Link to="detail/aaa">详情aaa</Link>
      </div>

      <div className='counter'>
        <Routes>
          <Route path='/detail/:id' element=<Detail/>/>
        </Routes>
      </div>

      <div className='footer'>footer</div>
    </div>
  )

  • 在跳转的页面中可以通过hook函数useParms获取到传入的id, 由于我们现在使用的是类组件, 无法使用hook函数, 因此需要通过高阶组件对当前组件增强(上一篇刚刚讲过高阶组件的封装, 这里直接使用, 给到大家代码)
import  useNavigate, useParams  from "react-router-dom"

export default function withRouter(WrapperComponent) 
  return function(props) 
    const naviagte = useNavigate()
    const params = useParams()
    const router = naviagte, params

    return <WrapperComponent ...props router=router />
  

  • 使用高阶组件增强当前Detail组件, 就可以通过useParams获取到传递的id
import React,  PureComponent  from 'react'
import withRouter from '../hoc/with_router'

export class Detail extends PureComponent 
  render() 
    // 获取到params
    const  params  = this.props.router

    return (
      <div>
        <h2>Detail</h2>
        /* 通过params获取到id并展示 */
        <h2>id: params.id</h2>
      </div>
    )
  


export default withRouter(Detail)

方式二: search传递参数(也就是查询字符串的方式), 这里在User组件中进行演示

  • 在路由跳转时拼接上查询字符串
render() 
  return (
    <div className='app'>
      <div className='header'>
        <Link to="/user?name=chenyq&age=18&height=1.88">用户</Link>
      </div>

      <div className='counter'>
        <Routes>
          <Route path='/user' element=<User/> />
        </Routes>
      </div>

      <div className='footer'>footer</div>
    </div>
  )

  • 查询字符串需要通过hook函数useSearchParams获取, 所以我们也需要使用高阶组件对User组件进行增强
// 封装的高阶组件

import  useNavigate, useParams, useSearchParams  from "react-router-dom"

export default function withRouter(WrapperComponent) 
  return function(props) 
    // 1.导航
    const naviagte = useNavigate()

    // 2.动态路由的参数
    const params = useParams()

    // 3.查询字符串的参数
    const [searchParams] = useSearchParams()
    const query = Object.fromEntries(searchParams.entries)

    const router = naviagte, params, query
    return <WrapperComponent ...props router=router />
  

  • 在组件中就可以获取到参数
import React,  PureComponent  from 'react'
import withRouter from '../hoc/with_router'

export class User extends PureComponent 
  render() 
    // 获取高阶组件中的query
    const  query  = this.props.router

    return (
      <div>
        <h2>User</h2>
        /* 通过query获取参数 */
        <h2>参数: query.name-query.age-query.height</h2>
      </div>
    )
  


export default withRouter(User)

路由的配置文件

目前我们所有的路由定义都是直接使用Route组件,并且添加属性来完成的

但是这样的方式会让路由变得非常混乱,我们希望像vue-router那样, 将所有的路由配置放到一个单独的文件进行集中管理:

在早期的时候,Router并且没有提供相关的API,我们需要借助于react-router-config完成;

在Router6.x中,为我们提供了useRoutes API可以完成相关的配置;

例如我们将下面的映射关系配置到一个单独的文件中

<div className='counter'>
  <Routes>
    /* 当默认路径 / 时, 重定向到home页面 */
    <Route path='/' element=<Navigate to="/home"/>></Route>
    /* 配置二级路由 */
    <Route path='/home' element=<Home/>>
      <Route path='/home' element=<Navigate to="/home/recommend"/>/>
      <Route path='/home/recommend' element=<HomeRecommend/>/>
      <Route path='home/ranking' element=<HomeRanking/>/>
    </Route>
    <Route path='/about' element=<About/>/>
    <Route path='/profile' element=<Profile/>/>
    <Route path='/category' element=<Category/>/>
    <Route path='/order' element=<Order/>/>
    <Route path='/detail/:id' element=<Detail/>/>
    <Route path='/user' element=<User/> />
    /* 当上面路径都没有匹配到时, 显式Notfound组件 */
    <Route path='*' element=<Notfound/>/>
  </Routes>
</div>

首先, 使用useRoutes这个API替代原来的Routes和Route组件, useRoutes可以当成一个函数直接使用, 但是只能在函数组件中使用

<div className='counter'>
  useRoutes(routes)
</div>

再在route/index.js中对映射关系进行配置

import  Navigate  from "react-router-dom"
import Home from '../pages/Home'
import About from '../pages/About'
import Profile from '../pages/Profile'
import Notfound from '../pages/Notfound'
import HomeRecommend from '../pages/HomeRecommend'
import HomeRanking from '../pages/HomeRanking'
import Category from '../pages/Category'
import Order from '../pages/Order'
import Detail from '../pages/Detail'
import User from '../pages/User'

const routes = [
  
    path: "/",
    element: <Navigate to="/home"/>
  ,
  
    path: "/home",
    element: <Home/>,
    children: [
      
        path: "/home",
        element: <Navigate to="/home/recommend" />
      ,
      
        path: "/home/recommend",
        element: <HomeRecommend/>
      ,
      
        path: "/home/ranking",
        element: <HomeRanking/>
      
    ]
  ,
  
    path: "/about",
    element: <About/>
  ,
  
    path: "/profile",
    element: <Profile/>
  ,
  
    path: "/category",
    element: <Category/>
  ,
  
    path: "/order",
    element: <Order/>
  ,
  
    path: "detail/:id",
    element: <Detail/>
  ,
  
    path: "/user",
    element: <User/>
  ,
  
    path: "*",
    element: <Notfound/>
  
]

export default routes

如果我们对某些组件进行了异步加载(懒加载, 分包处理),那么需要使用Suspense进行包裹:

例如我们对Detail和User进行懒加载(分包处理)

// import Detail from '../pages/Detail'
// import User from '../pages/User'

const Detail = React.lazy(() => import("../pages/Detail"))
const User = React.lazy(() => import("../pages/User"))

并且还需要使用Suspense对组件进行包裹

root.render(
  <HashRouter>
    <Suspense fallback=<h3>loading</h3>>
      <App/>
    </Suspense>
  </HashRouter>
)

React 学习笔记总结

文章目录

1. React 嵌套路由(多级路由)


要用到嵌套路由,就不能开启严格匹配。否则无法匹配二级路由的。

因为一级路由时/home ,所以可以通过模糊匹配进行操作,让一级路由对应组件和二级路由对应组件:

总结:

2. params参数 与 query参数


params参数 与 query参数格式:

# params参数如下格式:
params:/router1/id ,/router1/123,/router1/789 ,这里的id叫做params
# query参数如下格式:
query:/router1?id=123 ,/router1?id=456 ,这里的id叫做query。

3. React路由组件 传递params参数数据


Link的params参数传递:

对应路由Route要定义对应的key:

使用this.props.match.params获取params参数:


总结:

4. React路由组件 传递search参数


querystring库的使用:

  • 因为,query参数获取到后是?key1=value1&key2=value2形式。可以使用querystring库来转换成对象形式。

tips:自己封装也可以,但往往第三方写的要比自己封装的好一点。


search参数格式如下:

this.props.location.search参数来获取:

  • 获取到的是?key1=value1&key2=value2,要转成成对象形式。

总结:

5. React路由组件 传递search参数


获取路由组件state参数:

在this.props.location.state中获取参数:

总结:

6. React路由组件 特殊情况: 刷新页面


三种路由要注意一个特别情况:刷新页面。

主要说:state参数,刷新后,为什么没有小时!

因为浏览器的history模式,存储了state参数。

7. React路由 的 push 和 replace


push模式 和 replace模式:对浏览器历史记录的栈的一个推送或者替换效果。

8. React的 编程式路由


路由的三个特殊属性中有一个history属性:

# history属性作用:可以理解为就是专门来进行跳转路由的。
go: f go(n)
goBack: f goBack()
goForward: f goForward()
push: f push(path,state)
replace: f replace(path,state)

# 5个函数进行操作。

编程式路由:

  • 对应携带params参数、携带search参数、携带state参数。

通过this.props的history方法,进而调用replace,push方法来进行跳转路由。

总结:

9. React路由 withRouter


接受一个一般组件,然后将其加工为路由组件(路由组件对应的三个api)。

10. BrowserRouter 与 HashRouter的区别


BrowserRouter 与 HashRouter的区别

11. 开源的React UI组件库


material-ui(国外):http://www.material-ui.com

ant-design(国内蚂蚁金服):https://ant.design/index-cn

create-react-app的使用:https://ant-design.gitee.io/docs/react/use-with-create-react-app-cn

ant-design的按需引入:babel-plugin-import插件(v5已经移除)


早些版本是:config-overrides.js

新版本是:craco.config.js

这两个文件其实就是进行加工配置的,所以有些时候样式的按需引入等都可以进行加工操作。

12. antd 自定义主题


一般默认的antd主题是蓝色,想要改主题颜色之类的。

早些版本,可以通过config-overrides.js来进行加工配置。

新版本 自定义主题:https://ant-design.gitee.io/docs/react/customize-theme-cn

根据不同版本,看官方文档就行。

以上是关于React中路由的参数传递 - 路由的配置文件的主要内容,如果未能解决你的问题,请参考以下文章

React 向路由组件传递参数

React 学习笔记总结

ReactSPA - 路由机制 - react-router-dom - 基本路由 - 嵌套路由 - 传递参数 - 路由跳转

Nuxt的路由配置和参数传递

在 React Router 中,使用浏览器历史推送时如何传递路由参数?

路由传参和路由守卫