八、React Router (V6) 用法详解

327 阅读2分钟

一. 简介

  • 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。

二. 对比V5

  1. 包大小对比

image.png

  1. <Route> 特性变更

    path:与当前页面对应的URL匹配。

    element:新增,用于决定路由匹配时,渲染哪个组件。代替,v5的component和render。

  2. <Routes>代替了<Switch>

  3. <Outlet></Outlet>让嵌套路由更简单

  4. useNavigate代替useHistory

  5. 移除了<NavLink/>activeClassNameactiveStyle

  6. 钩子useRoutes代替react-router-config

  7. reactrouter.com/docs/en/v6/…

三. 用法详解

1. 一级路由与多级路由

<Routes>
    {/*<Route path="/" element={<Film/>}/>*/}
    <Route index element={<Film/>}/> 
    <Route path="/film" element={<Film/>}/>
    <Route path="/cinema" element={<Cinema/>}/>
    <Route path="/center" element={<Center/>}/>
</Routes>

index属性来指定默认路由:有多个子路由时,默认渲染哪个子路由

2. 路由重定向

  1. 使用 Navigate 组件替代
<Routes>
  
    <Route path="/film" element={<Film/>}/>
    <Route path="/cinema" element={<Cinema/>}/>
    <Route path="/center" element={<Center/>}/>
    <Route path="*" element={<Navigate to="/film"/>}/>
</Routes>
  1. 自定义 Redirect 组件 如果习惯用Redirect,可以用Navigate封装一个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/>}/>

3. 嵌套路由

<Route path="/film" element={<Film/>}>
    
    <Route path="" element={<Redirect to="/film/nowplaying"/>}/>
    <Route path="nowplaying" element={<Nowplaying/>}/>
    <Route path="comingsoon" element={<Comingsoon/>}/>
</Route>

Film组件 
    <Outlet></Outlet>

4. 声明式导航与编程式导航

//声明式导航
 <ul>
    <li><NavLink to="nowplaying" className={({ isActive }) => isActive ? "kerwinactive" : ""} >正在热映</NavLink></li>
    <li><NavLink to="comingsoon" className={({ isActive }) => isActive ? "kerwinactive" : ""}>即将上映</NavLink></li>
 </ul>
//编程式导航
//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})

5.动态路由

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

//配置动态路由
<Route path="/detail/:id" element={<Detail/>}/>
    
//获取动态路由参数
    
const {id} = useParams()

6.路由拦截

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

function AuthComponent(props){
    if(localStorage.getItem("token")){
        return <div>{props.children}</div> 
    }else{
        return <Redirect to="/login"/>
    }
    
}

7.路由模式

import {HashRouter} from 'react-router-dom'
import {BrowserRouter} from 'react-router-dom'

8. 路由懒加载

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

export default function MRouter() {
    return (
        <Routes>
            <Route path="/film" element={LazyLoad("Film")}>
                <Route path="" element={<Redirect to="/film/nowplaying"/>}/>
                <Route path="nowplaying" element={LazyLoad("film/Nowplaying")}/>
                <Route path="comingsoon" element={LazyLoad("film/Comingsoon")}/>
            </Route>
        </Routes>
    )
}

9. useRoutes钩子配置路由(推荐)

这种配置方式相比传统方式更方便

export default function MRouter() {
    const element = useRoutes([
        {
            path:"/film",element:LazyLoad("Film"),children:[
                {
                    path:"",
                    element:<Redirect to="/film/nowplaying"/>
                },
                {
                    path:"nowplaying",
                    element:LazyLoad("film/Nowplaying")
                },
                {
                    path:"comingsoon",
                    element:LazyLoad("film/Comingsoon")
                }
            ]
        },
        
        {
            path:"/login",element:LazyLoad("Login")
        },
        {
            path:"/center",element:<AuthComponent>{LazyLoad("Center")}</AuthComponent>
        },
        
    ])

    return element
}

本文非原创,仅做分享