一、概述

ReactRouter以三个不同的包发布到npm上它们分别为

1、react-router:路由的核心库,提供了很多的组件和钩子

2、react-router-dom。包含react-router所有的内容,并添加了一些专门用于DOM的组件,例如<BrowserRouter>等

3、react-router-native:包含react-router所有的内容,并添加了一些专门用于ReactNavtive的API,例如<NativeRouter>

二、Component

1、BrowserRouter

用于包裹整个应用,来让整个应用可以使用路由传参

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'

ReactDOM.render(
    <BrowserRouter>
        {/* 整体结构(通常为App组件)*/}
    </BrowserRouter>,
    root
)

2、HashRouter

说明:作用与BrowserRouter一样,但是HashRouter修改的是地址栏的hash值

备注:6.x版本中的HashRouter、BrowserRouter的用法与5.x相同

3、Routes与Route

1)、v6版本中移除了先前的Switch,引入了新的替代者Routes

2)、Routes和Route要配合使用,且必须要用Routes包裹Route

3)、Route相当于一个if语句,如果其路径与当前URL匹配,则呈现其对应的组件

4)、

<Route caseSensitive>

此属性用于指定,匹配时是否区分大小写,默认为false

5)、当URL变化时,Routes都会查看其所有子Route元素以找到最佳匹配并呈现组件

6)Route也可以嵌套使用,且可配合useRoutes()配置路由表,但需要通过Outlet组件来渲染其子路由

入口文件前置工作

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './App'

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
)

App.jsx文件,实现简单的需求

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

import About from './page/About.jsx'
import Home from './page/Home.jsx'

export default function App(){
    return(
        <div>
            // 路由链接
            <div>
                <NavLink to="/about">About</NavLink>
                <NavLink to="/home">Home</NavLink>
            </div>
            <div>
                // 注册路由,组件显示区
                <Routes>
                    <Route path="/about" element="{<About />}">
                    <Route path="/home" element="{<Home />}">
                </Routes>
            </div>
        <div>
    )
}

4、Link

5、NavLink  路由高亮

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

import About from './page/About.jsx'
import Home from './page/Home.jsx'

export default function App(){
    function computedClassName({isActive}){
        return isActive?'active_class':'default_class'
    }
    return(
        <div>
            // 路由链接
            <div>
                <NavLink to="/about">About</NavLink>
                <NavLink to="/home">Home</NavLink>
            </div>
            <div>
                // 注册路由,组件显示区
                <Routes>
                    //<Route className={(a)=>{console.log(a)}} path="/about"  element="{<About />}">
                    //a为 { isActive:true },即当该路由被点击激活时,此属性为true
                    
                    <Route className={(isActive)=> { return isActive?'active_class':'default_class'}} path="/about" element="{<About />}">
                    <Route className={(isActive)=> isActive?'active_class':'default_class'} path="/about1" element="{<AboutOther />}">
                    <Route className={ computedClassName } path="/home" element="{<Home />}">
                </Routes>
            </div>
        <div>
    )
}

6、Navigate 重定向

作用:只要Navigate组件被渲染,就会修改路径,切换视图

replace属性用于控制跳转模式,push或replace,默认是push

import React,{ useState } from 'react'
import { Navigate } from 'react-router-dom'

export default function Home(){
    const [ sum,setSum ] = useState(1)
    return (
        <div>
            {/* 根据sum的值决定是否切换视图 */}
            { sum === 1 ? <h4>sum的值为{sum}</h4>:<Navigate to="/about",replace={true} /> }
            <button onClick={()=>setState(2)}>将sum的值变为2</button>
        </div>
    )
}

7、OutLet 嵌套路由

import About from '...'
import Home from '...'
import Message from  '...'
import News from '...' 
import { Navigate } from 'react-router-dom'
export default [
    {
        path:"/about",
        element:<About />
    },
    {
        path:"/home",
        element:<Home />,
        children:[
            {
                path:"message", //不需要写/home/message
                element:<Message />
            },
            {
                path:"news",
                element:<News />
            },
        ]
    },
    {
        path:"/",
        element:<Navigate to="/about">
    },
]

在Home.jsx中

import React from 'react'
import { NavLink,Outlet } from 'react-router-dom'
export default Home(){
    return (
        <div>
            <h1>Home页的内容</h1>
            <ul>
                <li>
                    <NavLink to="news">News</NavLink>  {/* 地址栏为 /home/news */}
                    <NavLink to="/news">News</NavLink>  {/* 地址栏为 /news */}
                    <NavLink to="./news">News</NavLink>  {/* 地址栏为 /home/news */}
                </li>
                <li>
                    {/* 通常情况下,点击home路由,再点击home的子路由,这两个路由都会高亮,end可以让home不高亮 */}
                    <NavLink to="message" end>Message</NavLink>
                </li>
            </ul>
            {/* 指定嵌套路由组件呈现的位置 */}
            <Outlet />
        </div>
    )
}

三、Hooks

1、useRoutes()

import React from 'react'
import { NavLink,useRoutes } from 'react-router-dom'

import About from './page/About.jsx'
import Home from './page/Home.jsx'

export default function App(){
    const element = useRoutes({
        {
            path:"/about",
            element:<About />
        },
        {
            path:"/home",
            element:<Home />
        },
        {
            path:"/",
            element:<Navigate to="/about">
        },
    })
    return(
        <div>
            // 路由链接
            <div>
                <NavLink to="/about">About</NavLink>
                <NavLink to="/home">Home</NavLink>
            </div>
            <div>
                // 注册路由,组件显示区
                //<Routes>
                //    <Route path="/about" element="{<About />}">
                //    <Route path="/home" element="{<Home />}">
                //</Routes>
                {element}
            </div>
        <div>
    )
}

也可以将useRoutes整合到一个文件中,方便管理,通常创建routes.js或者routes/index.js文件

import About from '...'
import Home from '...'
import { Navigate } from 'react-router-dom'
export default [
    {
        path:"/about",
        element:<About />
    },
    {
        path:"/home",
        element:<Home />
    },
    {
        path:"/",
        element:<Navigate to="/about">
    },
]
import React from 'react'
import { NavLink,useRoutes } from 'react-router-dom'

//引入上述的路由表
import routes from '...'

export default function App(){
    //根据路由表生成路由规则
    const element = useRoutes(routes)
    return(
        <div>
            // 路由链接
            <div>
                <NavLink to="/about">About</NavLink>
                <NavLink to="/home">Home</NavLink>
            </div>
            <div>
                // 注册路由,组件显示区
                //<Routes>
                //    <Route path="/about" element="{<About />}">
                //    <Route path="/home" element="{<Home />}">
                //</Routes>
                {element}
            </div>
        <div>
    )
}

2、useNavigate()  编程式路由导航

import React from 'react'
import { useState,useNavigate } from 'react-router-dom'

export default Demo(){
    const navigate = useNavigate()
    const [ demoList ] = useState(
        [
            { id:'001',title:'消息一',content:'屏幕光深夜渐阑' },
            { id:'002',title:'消息二',content:'键声敲碎半更寒' },
            { id:'003',title:'消息三',content:'案头未改青丝色' },
            { id:'004',title:'消息四',content:'心底新添代码宽' }
        ]
    )

    //replace,state参数是固定的,如果想传递params参数或search参数,请在to参数修改设置
    function goDetail(item){
        navigate(
            to:'detail',
            replace:false,
            state:{
                id:item.id,
                title:item.title,
                content:item.content
            }
        )
    }

   function goBack(){
        navigate(-1)
    }

    function goForward(){
        navigate(1)
    }
    return (
        <div>
            <ul>
                demoList.map(item=>{
                    <li>
                        {item.title}<button onClick={()=>goDetail(item)}>详情</button>
                    </li>
                })
            </ul>
            <button onClick={goBack}>前进</button>
            <button onClick={goForward}>后退</button>
        </div>
    )
}

3、useParams() params传参

import About from '...'
import Home from '...'
import Message from  '...'
import News from '...' 
import Deatil from '...'
import { Navigate } from 'react-router-dom'
export default [
    {
        path:"/about",
        element:<About />
    },
    {
        path:"/home",
        element:<Home />,
        children:[
            {
                path:"message", //不需要写/home/message
                element:<Message />,
                children:[
                     {
                        path:"detail/:id/:title/:content",
                        element:<Detail />
                     },
                ]
            },
            {
                path:"news",
                element:<News />
            },
        ]
    },
    {
        path:"/",
        element:<Navigate to="/about">
    },
]

Message.jsx页面

import React,{useState} from 'react'
import { NavLink,Outlet } from 'react-router-dom'
export default Home(){
       const [messages] = useState(
                [
                    { id:"001",title:"消息1",message:"屏幕光深夜渐阑" },
                    { id:"002",title:"消息2",message:"键声敲碎半更寒" },
                    { id:"003",title:"消息3",message:"案头未改青丝色" },
                    { id:"004",title:"消息4",message:"心底新添代码宽" },
                ]
            )
    return (
        <div>
            <h1>Message页的内容</h1>
            <ul>
               {
                    messages.map(item=>{
                        return <li key={item.id} >
                                    <NavLink to={`detail/${item.id}/${item.title}/${item.message}`}> {item.title} </NavLink>
                                </li>
                    })
                }
            </ul>
            {/* 指定嵌套路由组件呈现的位置 */}
            <Outlet />
        </div>
    )
}

Detail.jsx页面

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

export default function Detail(){
    const { id,title,message } = useParams()
    return (
        <ul>
            <li>{id}</li>
            <li>{title}</li>
            <li>{message}</li>
        </ul>
    )
}

4、useSearchParams()

{
        path:"/home",
        element:<Home />,
        children:[
            {
                path:"message",
                element:<Message />,
                children:[
                     {
                        path:"detail?",
                        element:<Detail />
                     },
                ]
            },
            {
                path:"news",
                element:<News />
            },
        ]
    },




<ul>
   {
      messages.map(item=>{
         return <li key={item.id} >
                     <NavLink to={`detail?id=${item.id}&title=${item.title}&message=${item.message}`}> {item.title} </NavLink>
                </li>
      })
    }
</ul>





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

export default function Detail(){
    const [ search,setSearch ] = useSearchParams()
    return (
        <ul>
            <li>{search.get('id')}</li>
            <li>{search.get('title')}</li>
            <li>{search.get('message')}</li>
        </ul>
    )
}

//setSearch可以更改收到的search参数,地址栏也会改变
//onClick={()=>setSearch('id=005&title=测试&message=哈哈')}

5、useLocation()

useLocation 返回一个 location 对象,该对象包含以下关键属性:

  • ‌pathname‌: 当前 URL 的路径部分(例如 /about)。
  • ‌search‌: URL 中的查询字符串部分(例如 ?id=100&name=Tom)。
  • ‌hash‌: URL 中的哈希部分(例如 #section1)。
  • ‌state‌: 路由跳转时通过 navigate 或 <Link> 传递的状态数据对象。
  • ‌key‌: 唯一标识当前 location 的字符串。
import { useLocation } from 'react-router-dom';

function CurrentPathInfo() {
  const location = useLocation();

  return (
    <div>
      <h2>当前路由信息</h2>
      <p>路径: {location.pathname}</p>
      <p>查询参数: {location.search}</p>
      <p>哈希: {location.hash}</p>
      <p>状态数据: {JSON.stringify(location.state)}</p>
    </div>
  );
}

6、useMatch()

用于‌判断当前 URL 是否与指定路径模式匹配‌的 Hook。如果匹配成功,它返回一个包含匹配详细信息的对象;如果不匹配,则返回 null。

它常用于动态路由参数提取、条件渲染(如导航高亮)以及实现更精细的路由控制逻辑。

  • 匹配成功‌:返回一个对象,包含 params(动态参数)、pathname(匹配的路径片段)、pattern(使用的匹配模式配置)等。
  • ‌匹配失败‌:返回 null

7、useInRouterContext()

作用:如果组件在<Router>的上下文中呈现,则 useInRouterContext()钩子返回true,否则返回false

之前我们在入口文件中,为整个App包裹了BrowserRouter,所以你在任何组件执行useInRouterContext()钩子的话都是返回true的

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './App'

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
)

8、useNavigationType()

作用:返回当前的导航类型(用户是如何来到当前页面的)

返回值:POP、PUSH、REPLACE

备注:POP是指在浏览器中直接打开了这个路由组件(刷新页面)

9、useOutlet()

作用:用来呈现当前组件中要渲染的嵌套路由

const result = useOutlet()
console.log(result)
//如果嵌套路由没有挂载,则result为null
//如果嵌套路由已经挂载,则展示嵌套的路由对象

10、useResolvedPath()

作用:给定一个URL值,解析其中的path、search、hash值

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐