react学习 第十一天 React-Router路由详解 router6

目录:

1 认识React-Router

2 Router的基本使用

3 Router的路由嵌套

4 Router的代码跳转

5 Router的参数传递

6 Router的配置方式

一、认识React-Router

 

扫描二维码关注公众号,回复: 14827256 查看本文章

 

 

 

二、Router的基本使用

1、在app.jsx的index.js文件里面引入router和严格模式

2、配置路由映射 ,在需要使用router的组件里面使用Router和route组件以及Link组件,通过点击Link组件来跳转url

import { Link, Route, Routes } from 'react-router-dom'

 3、通过给的NavLink组件来做到点击之后的NavLink内容发生css样式的变化,后续使用button来做跳转的时候比较好,可以自己控制跳转,NavLink不好控制。

通过NavLink组件被点击之后会给组件添加.active的类名,可以在css文件里面添加该类的样式从而控制NavLink被点击之后的样式。

另外一种变色的方法:

 如果怕这个类名会冲突,可以使用下面的方法来实现改变样式:

 

4、重定向(Navigate组件)使用举例,登录成功之后跳转到首页:

 重定向还有一个作用就是可以在网站默认页/的时候主动跳转到你给定的地址,下图是在页面:

 在用户进入到没有页面的路由路径的时候,我们可以设置notfound页面来提示用户没有此页面:不能限定path路径,可以通过*来设置通配,当url地址不是上面的任何一个的时候跳转到notfound页面。

 

 

 

 

 

 

三、Router的路由嵌套

1、在app.jsx组件里面添加:因为跳转到/home的时候需要重定向子组件跳转到一个默认的子组件来显示东西,不然跳转过去没有东西。

在/home的组件里面添加link点击跳转的按钮和占位符outlet:

四、Router的代码跳转

注意:useNavigate是个函数,不可以在类组件里面调用,可以在函数式组件里面使用

由于link组件渲染出来是个a标签,不能给属性,所以需要手动跳转路由的方式来改变标签类型:

1、在函数式组件中使用手动跳转路由

引入useNavigate并使用,

2、类组件中实现手动跳转:(需要使用增强)

(1)创建hoc文件夹,文件夹底下放

index.js代码:

import withRouter from "./with_router";

export {
  withRouter
}

 with_router.js代码:

import { useState } from "react"
import { useLocation, useNavigate, useParams, useSearchParams } from "react-router-dom"

// 高阶组件: 函数
function withRouter(WrapperComponent) {
  return function(props) {
    // 1.导航,为了类组件实现手动跳转的
    const navigate = useNavigate()

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

    // 3.查询字符串的参数: /user?name=why&age=18
    const location = useLocation()
    const [searchParams] = useSearchParams()
    const query = Object.fromEntries(searchParams)

    const router = { navigate, params, location, query }

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

export default withRouter

需要使用增强的组件,需要手动跳转路由的组件代码:

import React, { PureComponent } from 'react'
import { Link, Outlet } from 'react-router-dom'
import { withRouter } from "../hoc"

export class Home extends PureComponent {
//跳转的方法
  navigateTo(path) {
    const { navigate } = this.props.router
    navigate(path)
  }

  render() {
    return (
      <div>
        <h1>Home Page</h1>
        <div className='home-nav'>
          <Link to="/home/recommend">推荐</Link>
          <Link to="/home/ranking">排行榜</Link>
          <button onClick={e => this.navigateTo("/home/songmenu")}>歌单</button>
        </div>

        {/* 占位的组件 */}
        <Outlet/>
      </div>
    )
  }
}

export default withRouter(Home)

五、Router的参数传递

第一种方法是动态路由的方式传递可见的参数,需要使用增强:

(1)需要跳转页面的组件使用上面手动跳转的方式来在url里面添加参数

import React, { PureComponent } from 'react'
import { withRouter } from "../hoc"

export class HomeSongMenu extends PureComponent {
  constructor(props) {
    super(props)

    this.state = {
      songMenus: [
        { id: 111, name: "华语流行" },
        { id: 112, name: "古典音乐" },
        { id: 113, name: "民谣歌曲" },
      ]
    }
  }

  NavigateToDetail(id) {
    const { navigate } = this.props.router
    navigate("/detail/" + id)
  }

  render() {
    const { songMenus } = this.state

    return (
      <div>
        <h1>Home Song Menu</h1>
        <ul>
          {
            songMenus.map(item => {
              return <li key={item.id} onClick={e => this.NavigateToDetail(item.id)}>{item.name}</li>
            })
          }
        </ul>
      </div>
    )
  }
}

export default withRouter(HomeSongMenu)

(2)在hoc文件夹里的增强组件的函数里面添加把参数传递到router自定义属性里面。

import { useState } from "react"
import { useLocation, useNavigate, useParams, useSearchParams } from "react-router-dom"

// 高阶组件: 函数
function withRouter(WrapperComponent) {
  return function(props) {
    // 1.导航
    const navigate = useNavigate()

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

    // 3.查询字符串的参数: /user?name=why&age=18
    const location = useLocation()
    const [searchParams] = useSearchParams()
    const query = Object.fromEntries(searchParams)

    const router = { navigate, params, location, query }

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

export default withRouter

(3)在跳转到的组件里面填写接收的方法

import React, { PureComponent } from 'react'
import { withRouter } from '../hoc'

export class Detail extends PureComponent {
  render() {
    const { router } = this.props
    const { params } = router

    return (
      <div>
        <h1>Detail Page</h1>
        <h2>id: {params.id}</h2>
      </div>
    )
  }
}

export default withRouter(Detail)

第二种方法:拼接参数,查询字符串的参数

 

(1)可以通过useLocation来获取参数,但是很麻烦,不建议用

 

(2)还可以通过useSearchParams

在hoc的组件增强函数里面添加下面这个方法

 然后在需要使用拼接参数的值:

import React, { PureComponent } from 'react'
import { withRouter } from '../hoc'

export class User extends PureComponent {
  render() {
    const { router } = this.props
    const { query } = router

    return (
      <div>
        <h1>User: {query.name}-{query.age}</h1>
      </div>
    )
  }
}

export default withRouter(User)

六、Router的配置方式

上面提到的router都是配置在app.jsx文件里面的,不好管理和配置,于是我们和vue一样设置一个名字叫router的文件夹来存放对应的配置信息:

文件夹:

index.js的内容是:

从原来的

 变成了下面的:

import Home from '../pages/Home'
import HomeRecommend from "../pages/HomeRecommend"
import HomeRanking from "../pages/HomeRanking"
import HomeSongMenu from '../pages/HomeSongMenu'
// import About from "../pages/About"
// import Login from "../pages/Login"
import Category from "../pages/Category"
import Order from "../pages/Order"
import NotFound from '../pages/NotFound'
import Detail from '../pages/Detail'
import User from '../pages/User'
import { Navigate } from 'react-router-dom'
import React from 'react'

const About = React.lazy(() => import("../pages/About"))
const Login = React.lazy(() => import("../pages/Login"))

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: "/home/songmenu",
        element: <HomeSongMenu/>
      }
    ]
  },
  {
    path: "/about",
    element: <About/>
  },
  {
    path: "/login",
    element: <Login/>
  },
  {
    path: "/category",
    element: <Category/>
  },
  {
    path: "/order",
    element: <Order/>
  },
  {
    path: "/detail/:id",
    element: <Detail/>
  },
  {
    path: "/user",
    element: <User/>
  },
  {
    path: "*",
    element: <NotFound/>
  }
]


export default routes

在App.jsx文件夹里面需要使用useRouters来生成和原来一样的router结构:

 不能直接用 {useRoutes}要写成下面的形式

 {useRoutes(routes)}

路由的懒加载(单独打包,提升性能):

在之前配置的router文件夹底下的index.js文件里面把需要懒加载的组件import引入的形式写成:

其次,在App.jsx文件对应的index.js里面的<app/>需要被组件<Suspense fallback={<h3>Loading</h3>}></Suspense>包裹才不会报错。Suspense组件的作用是因为懒加载需要下载对应的组件文件,这个时候提示消息Loading...

import { Suspense } from "react"

猜你喜欢

转载自blog.csdn.net/weixin_56663198/article/details/129248736