第三十四章:ReactRouter V6

react-router-dom@6

官方文档

路由的三种模块

  • react-router :核心模块,包含 React 路由大部分的核心功能,包括路由匹配算法和大部分核心组
    件和钩子。
  • react-router-dom:React应用中用于路由的软件包,包括react-router的所有内容,并添加了一
    些特定于 DOM 的 API,包括但不限于BrowserRouter、HashRouter和Link。
  • react-router-native: 用于开发React Native应用,包括react-router的所有内容,并添加了一些
    特定于 React Native 的 API,包括但不限于NativeRouter和Link。

与之前的变化

  • path:与当前页面对应的URL匹配。
  • element:用于决定路由匹配时渲染哪个组件,代替 component 和 render。
  • <Outlet></Outlet> 让嵌套路由更简单
  • useNavigate 代替 useHistory
  • 移除了 activeClassName 和 activeStyle
  • 钩子 useRoutes 代替 react-router-config

使用

一级 多级

  • index用于嵌套路由,仅匹配父路径时,设置渲染的组件。
<Routes>
      <Route index path='/film' element={<Film />}/>
      <Route path='/cinema' element={<Cinema />}/>
      <Route path='/center' element={<Center />}/>
      <Route path='/cinema/search' element={<Search />}/>
      <Route path='*' element={<NotFound/>}/>
    </Routes>

路由重定向

1: 使用 Navigate 组件替代(官方推荐方案)

{/* <Route index element={<Film/>}/> */}

2: 自定义 Redirect 组件(官方推荐方案)

<Route path="*" element={<Redirect to="/film"/>}/> 

function Redirect({to}){ 
    const navigate =useNavigate()
   useEffect(() => { 
      navigate(to,{replace:true}) 
    })
        return null
 }
  1. 404如何实现?
<Route path="/" element={<Redirect to="/film"/>}/>
<Route path="*" element={<NotFound/>}/>

嵌套路由

<Routes>
      <Route path='/film' element={<Film />}>
        {/* <Route index element={<Nowpalying/>}/> */}  { /* 嵌套重定向一 index */ }
        <Route path='' element={<Redirect to='/film/nowplaying'/>}/> { /* 嵌套重定向写法二 path路径默认情况 重定向到nowplaying组件 */ }
        <Route path='/film/nowplaying' element={<Nowpalying/>}/>  { /* 嵌套写法 :1. 绝对路径写法 */ }
        <Route path='comingsoon' element={<Comingsoon/>}/>  { /* 嵌套写法 :2. 相对路径写法 */ }
      </Route>
      <Route path='/cinema' element={<Cinema />}/>
      <Route path='/center' element={<Center />}/>
      <Route path='/cinema/search' element={<Search />}/>

       {/* <Route path="*" element={<Navigate to="/films"/>}/>  */}
      <Route path='/' element={<Redirect to={'/film'}/>}/>
      <Route path='*' element={<NotFound/>}/>
    </Routes>

声明式导航和编程式导航

声明式:<a href=' / ' ></a>
编程式:location.href = ' / '

声明式导航

  • NavLink 与 Link 都可以实现路由跳转,NavLInk 拥有 active
  • className 接收一个回调函数 ,active返回true,其他返回false
<NavLink to='/film' className={({isActive})=>isActive?'tabbar-active':''}>电影</NavLink>

编程式导航

//url传参 
const navigate = useNavigate() 
navigate(`/detail?id=${id}`)

//获取url参数 import { useSearchParams } from 'react-router-dom' 
const [searchParams, setSearchParams] = useSearchParams() 
// 获取参数
 searchParams.get('id')
 // 判断参数是否存在
 searchParams.has('id') 
// 同时页面内也可以用set方法来改变路由 
setSearchParams({"id":2})

动态传参

//跳转页面,路由传参 
navigate(`/detail/${id}`) 

//配置动态路由 
<Route path="/detail/:id" element={<Detail/>}/> 

//获取动态路由参数 
const {id} = useParams()

路由拦截

<Route path="/center" element={ 
  <AuthComponent> 
    <Center></Center> 
  </AuthComponent> }/>

 function AuthComponent({children}){
   return localStorage.getItem("token")? children:<Redirect to="/login"/> 
}

withRouter / 类组件跳转方法

  • v6 中没有 withRouter 方法
  • 在旧的类组件项目中可通过封装高阶组件实现
    方法封装
import React from 'react'
import {
  useNavigate,
  useParams, 
  useLocation
} from 'react-router-dom'

export default function withRouter(Component) {
  return function (props) {
    const push = useNavigate()
    const match = useParams()
    const location = useLocation()
    return <Component {...props} history={{push, match, location}}/>
  }
}

路由懒加载

  • 方法封装
import React from "react"

const LazyLoad = (path)=>{
  const Comp = React.lazy(()=>import(`../views/${path}`))
  return (
      <React.Suspense fallback={<>加载中....</>}>
          <Comp/>
      </React.Suspense>
  )
}

export default LazyLoad

useRoutes钩子配置路由

import Redirect from '../components/Redirect';
import AuthComponent from '../components/AuthComponent';
import { useRoutes } from 'react-router-dom';
import LazyLoad from '../components/LazyLoad'

export default function MRouter() {
  const routes = useRoutes([
    {
      path: '/film', 
      element: LazyLoad('Film'),
      children: [
        {
          path: '',
          element: <Redirect to={'/film/nowplaying'}/>
        },
        {
          path: '/film/nowplaying',
          element: LazyLoad('film/Nowplaying')
        },
        {
          path: 'co mingsoon',
          element: LazyLoad('film/Comingsoon')
        }
      ]
    },
    {
      path: '/cinema',
      element: LazyLoad('Cinema')
    },
    {
      path: '/center',
      element: <AuthComponent>
        {LazyLoad('Center')}
      </AuthComponent>
    },
    {
      path: `/detail/:id`,
      element: LazyLoad('Detail')
    },
    {
      path: '/cinema/search',
      element: LazyLoad('Search')
    },
    {
      path: 'login',
      element: LazyLoad('Login')
    },
    {
      path: '/',
      element: LazyLoad('/film')
    },
    {
      path: '*',
      element: LazyLoad('NotFound')
    }
  ])
  return (
    routes
  )
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容