React-RouterV6版本的使用

React-RouterV6

https://reactrouter.com/en/main/components/routes

简介
  • react-router :核心模块‘ react路由的大部分的核心功能,包括路由匹配算法和大部分的核心组件和钩子

  • react-router-dom React组件中用于路由的软件包,包括react-router的所有内容,还添加了一些特定的Dom的api

  • react-router-native 开发reactNavite应用,包括react-router的所有内容,添加了一些react-native的api

react-routerV6版本和V5版本的区别
  • 包大小的不同 V5 大小在20.8k左右,压缩后在7.3k左右;V6 大小在10.8k左右,压缩后在3.8k左右
  • Route 特性变更
    • path 当前页面对应的URL地址
    • element 路由匹配时,渲染哪个组件 ;替代了V5里的component和render
  • Routes替代了Switch
  • 嵌套路由更简单
  • useNavigate替代了useHistory
  • 移除了activeClassName
  • 钩子useRoutes替代了react-router-config
路由使用
  • 路由表配置

    src/router/index.js

    import React from 'react'
    
    import { Routes, Route } from 'react-router-dom'
    
    import Home from '../Home'
    import Course from '../Course'
    
    export default function MRoute() {
      return (
        // Routes替代了Switch
        <Routes>
          {/* element替代了component */}
          <Route path="/home" element={<Home />}></Route>
          <Route path="/course" element={<Course />}></Route>
        </Routes>
      )
    }
    
    
  • 路由视图

    App.js

    import React from 'react'
    import { BrowserRouter as Router } from 'react-router-dom'
    // 引入路由表
    import MRoute from './router'
    
    export default function App() {
      return (
        <Router>
          <MRoute />
        </Router>
      )
    }
    
    
路由重定向

React-routerV6版本中已经没有了Redirect组件

  • 第一种:使用Navigate组件替代

    src/router/index.js

    import React from 'react'
    
    import { Routes, Route, Navigate } from 'react-router-dom'
    
    import Home from '../Home'
    import Course from '../Course'
    
    export default function MRoute() {
      return (
        // Routes替代了Switch
        <Routes>
          {/* element替代了component */}
          <Route path="/home" element={<Home />}></Route>
          <Route path="/course" element={<Course />}></Route>
          {/* 路由重定向 */}
          <Route path="/" element={<Navigate to="/home" />}></Route>
        </Routes>
      )
    }
    
    
  • 第二种:自定义Redirect组件

    import { useEffect } from 'react'
    import { useNavigate } from 'react-router-dom'
    
    export default function Redirect(props) {
      const navigate = useNavigate()
      useEffect(() => {
        // replace: true 代表的是要替换掉之前的页面
        navigate(props.to, { replace: true })
      })
      return null
    }
    
    
    <Routes>
          {/* element替代了component */}
          <Route path="/home" element={<Home />}></Route>
          <Route path="/course" element={<Course />}></Route>
          {/* 路由重定向 */}
          <Route path="/" element={<Redirect to="/home" />}></Route>
        </Routes>
    
  • 404页面

    <Routes>
          {/* element替代了component */}
          <Route path="/home" element={<Home />}></Route>
          <Route path="/course" element={<Course />}></Route>
          {/* 路由重定向 */}
          <Route path="/" element={<Redirect to="/home" />}></Route>
          {/* 404页面 */}
          <Route path="*" element={<NotFound />}></Route>
    </Routes>
    
声明式导航和编程式导航
  • 声明式导航

    <Router>
          <NavLink to="/home">首页</NavLink>
          <NavLink to="/course">课程</NavLink>
          <hr />
          <MRoute />
        </Router>
    

NavLink组件会自动给当前的匹配到的路由NavLink添加一个class名为active,要实现高亮效果设置active样式

​ 自定义class名

<Router>
      <NavLink
        to="/home"
        className={({ isActive }) => (isActive ? 'my-active' : '')}
      >
        首页
      </NavLink>
      <NavLink
        to="/course"
        className={({ isActive }) => (isActive ? 'my-active' : '')}
      >
        课程
      </NavLink>
      <hr />
     <MRoute />
 </Router>

NavLink有一个属性className,它接收一个函数,该函数的参数是一个对象,里面有一个属性isActive,

我们可以根据这个属性的值是否为true来判断是否添加class名

  • 编程式导航

    import React from 'react'
    import { useNavigate } from 'react-router-dom'
    
    export default function Home() {
      // 使用useNavigate这个钩子 可以通过js的方式实现跳转
      const navigate = useNavigate()
      return (
        <div>
          <div>Home</div>
          <button onClick={() => navigate('/course')}>去课程</button>
        </div>
      )
    }
    
嵌套路由
  • 基本配置

    import React from 'react'
    
    import { Routes, Route, Navigate } from 'react-router-dom'
    
    import Home from '../Home'
    import Course from '../Course'
    
    import Redirect from '../Redirect'
    import NotFound from '../NotFound'
    
    import JsCourse from '../JsCourse'
    import VueCourse from '../VueCourse'
    import ReactCourse from '../ReactCourse'
    
    export default function MRoute() {
      return (
        // Routes替代了Switch
        <Routes>
          {/* element替代了component */}
          <Route path="/home" element={<Home />}></Route>
          <Route path="/course" element={<Course />}>
            {/* 嵌套路由 */}
            {/* index匹配到的父路径 */}
            <Route index element={<Redirect to="/course/js" />}></Route>
            <Route path="js" element={<JsCourse />}></Route>
            <Route path="vue" element={<VueCourse />}></Route>
            <Route path="react" element={<ReactCourse />}></Route>
          </Route>
          {/* 路由重定向 */}
          <Route path="/" element={<Redirect to="/home" />}></Route>
          {/* 404页面 */}
          <Route path="*" element={<NotFound />}></Route>
        </Routes>
      )
    }
    
    
  • 通过Outlet组件实现嵌套路由的视图显示

    import React from 'react'
    
    import { NavLink, Outlet } from 'react-router-dom'
    
    export default function Course() {
      return (
        <div>
          <NavLink to="/course/js">js课程</NavLink>
          <NavLink to="/course/vue">vue课程</NavLink>
          <NavLink to="/course/react">react课程</NavLink>
          <hr />
          <Outlet />
        </div>
      )
    }
    
动态路由
  • query形式传参

    export default function Home() {
    // 使用useNavigate这个钩子 可以通过js的方式实现跳转
    const navigate = useNavigate()
    return (
    
      <div>
        <div>Home</div>
        <button onClick={() => navigate('/course')}>去课程</button>
        {/* 新闻 */}
        <NavLink to="/news?id=1">军事新闻</NavLink>
        <NavLink to="/news?id=2">体育e新闻</NavLink>
        <NavLink to="/news?id=3">娱乐新闻</NavLink>
      </div>
    
      )
    }
    
//路由配置
<Routes>
      {/* element替代了component */}
      <Route path="/home" element={<Home />}></Route>
      <Route path="/course" element={<Course />}>
        {/* 嵌套路由 */}
        {/* index匹配到的父路径 */}
        <Route index element={<Redirect to="/course/js" />}></Route>
        <Route path="js" element={<JsCourse />}></Route>
        <Route path="vue" element={<VueCourse />}></Route>
        <Route path="react" element={<ReactCourse />}></Route>
      </Route>
      {/* 新闻 */}
      <Route path="/news" element={<News />}></Route>
      {/* 路由重定向 */}
      <Route path="/" element={<Redirect to="/home" />}></Route>
      {/* 404页面 */}
      <Route path="*" element={<NotFound />}></Route>
    </Routes>
//News.js  获取参数
import React from 'react'
import { useSearchParams } from 'react-router-dom'

export default function News() {
  // 通过useSearchParams钩子函数来获取query形式的参数
  const [searchparams, setSearchParams] = useSearchParams()
  return <div>News{searchparams.get('id')}</div>
}

/* 
searchparams.get('id')  获取路由参数的值
searchparams.has('id')  判断参数是否存在

setSearchParams({'id':45}) 在当前页面修改路由参数的值
*/
  • params形式传参
import React from 'react'

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

export default function NewsDetail() {
  // 通过useParams 接收params传递的参数
  const params = useParams()
  return <div>NewsDetail{params.id}</div>
}
<Routes>
      {/* element替代了component */}
      <Route path="/home" element={<Home />}></Route>
      <Route path="/course" element={<Course />}>
        {/* 嵌套路由 */}
        {/* index匹配到的父路径 */}
        <Route index element={<Redirect to="/course/js" />}></Route>
        <Route path="js" element={<JsCourse />}></Route>
        <Route path="vue" element={<VueCourse />}></Route>
        <Route path="react" element={<ReactCourse />}></Route>
      </Route>
      {/* 新闻 */}
      <Route path="/news" element={<News />}></Route>
      {/* params形式 */}
      <Route path="/newsdetail/:id" element={<NewsDetail></NewsDetail>}></Route>
      {/* 路由重定向 */}
      <Route path="/" element={<Redirect to="/home" />}></Route>
      {/* 404页面 */}
      <Route path="*" element={<NotFound />}></Route>
    </Routes>
 {/* params形式传参 */}
      <NavLink to="/newsdetail/1">军事新闻</NavLink>
      <NavLink to="/newsdetail/2">体育e新闻</NavLink>
      <NavLink to="/newsdetail/3">娱乐新闻</NavLink>
路由拦截
  • 路由拦截组件封装

    //AuthComponent.js
    import React from 'react'
    import Redirect from './Redirect'
    
    export default function AuthComponent(props) {
      // 获取当前组件
      const Comp = props.children.type
      return localStorage.getItem('token') ? <Comp /> : <Redirect to="/login" />
    }
    
  • 配置登录拦截

     <Routes>
          {/* element替代了component */}
          <Route
            path="/home"
            element={
              <AuthComponent>
                <Home />
              </AuthComponent>
            }
          ></Route>
          <Route path="/login" element={<Login />}></Route>
          {/* params形式 */}
          <Route path="/newsdetail/:id" element={<NewsDetail></NewsDetail>}></Route>
          {/* 路由重定向 */}
          <Route path="/" element={<Redirect to="/home" />}></Route>
          {/* 404页面 */}
          <Route path="*" element={<NotFound />}></Route>
        </Routes>
    
  • 登录功能

    import React from 'react'
    import { useNavigate } from 'react-router-dom'
    
    export default function Login() {
      const navigate = useNavigate()
      const login = () => {
        localStorage.setItem('token', '112222')
        navigate('/home')
      }
      return (
        <div>
          <button onClick={login}>登录</button>
        </div>
      )
    }
    
路由懒加载
import React, { Suspense } from 'react'

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

// 通过React.lazy函数配合import 函数实现按需导入模块
const Home = React.lazy(() => import('../Home'))
const Course = React.lazy(() => import('../Course'))
const Login = React.lazy(() => import('../Login'))
const News = React.lazy(() => import('../News'))
const NewsDetail = React.lazy(() => import('../NewsDetail'))
const Redirect = React.lazy(() => import('../Redirect'))
const NotFound = React.lazy(() => import('../NotFound'))
const JsCourse = React.lazy(() => import('../JsCourse'))
const VueCourse = React.lazy(() => import('../VueCourse'))
const ReactCourse = React.lazy(() => import('../ReactCourse'))
const AuthComponent = React.lazy(() => import('../AuthComponent'))

export default function MRoute() {
  return (
    // 使用Suspense组件包裹所有路由表
    <Suspense>
      // Routes替代了Switch
      <Routes>
        {/* element替代了component */}
        <Route
          path="/home"
          element={
            <AuthComponent>
              <Home />
            </AuthComponent>
          }
        ></Route>
        <Route path="/course" element={<Course />}>
          {/* 嵌套路由 */}
          {/* index匹配到的父路径 */}
          <Route index element={<Redirect to="/course/js" />}></Route>
          <Route path="js" element={<JsCourse />}></Route>
          <Route path="vue" element={<VueCourse />}></Route>
          <Route path="react" element={<ReactCourse />}></Route>
        </Route>
        {/* 新闻 */}
        <Route path="/news" element={<News />}></Route>
        <Route path="/login" element={<Login />}></Route>
        {/* params形式 */}
        <Route
          path="/newsdetail/:id"
          element={<NewsDetail></NewsDetail>}
        ></Route>
        {/* 路由重定向 */}
        <Route path="/" element={<Redirect to="/home" />}></Route>
        {/* 404页面 */}
        <Route path="*" element={<NotFound />}></Route>
      </Routes>
    </Suspense>
  )
}

useRoutes钩子配置路由
  • 路由懒加载组件封装

    import React, { lazy, Suspense } from 'react'
    
    export default function LazyLoad(path) {
      const Element = lazy(() => import(`./${path}`))
      return (
        <Suspense>
          <Element />
        </Suspense>
      )
    }
    
    
  • 使用useRoutes钩子将路由转成配置文件

    import React, { Suspense } from 'react'
    import { useRoutes } from 'react-router-dom'
    import LazyLoad from '../LazyLoad'
    import Redirect from '../Redirect'
    
    export default function MRoute() {
      const element = useRoutes([
        {
          path: '/',
          element: <Redirect to="/home"></Redirect>,
        },
        {
          path: '/home',
          element: LazyLoad('Home'),
        },
        {
          path: '/course',
          element: LazyLoad('Course'),
    
          children: [
            {
              path: 'js',
              element: LazyLoad('JsCourse'),
            },
            {
              path: 'vue',
              element: LazyLoad('VueCourse'),
            },
            {
              path: 'react',
              element: LazyLoad('ReactCourse'),
            },
            {
              path: '',
              element: <Redirect to="/course/js"></Redirect>,
            },
          ],
        },
        {
          path: '/news',
          element: LazyLoad('News'),
        },
        {
          path: '/newsdetail/:id',
          element: LazyLoad('NewsDetail'),
        },
        { path: '*', element: LazyLoad('NotFound') },
      ])
    
      return element
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值