• React学习(七)— 路由react-router


    一、react-router

    和vue一样,react应用也是单页面应用(spa),所以也需要引入路由来控制不同组件的展示和隐藏来实现不同页面的效果,保持 UI 与 URL 的同步。

    安装:

    npm  i  react-router-dom  // 不指定版本号就是最新版本
    
    • 1

    在这里插入图片描述
    可以看到,最新的版本是6.3.0,也就是react-router v6。

    二、路由模式

    2.1 history模式

    history 模式,引入对应的组件是 BrowserRouter 组件。

    import React  from "react"
    import ReactDOM  from "react-dom/client"
    
    // 引入路由组件  使用 as 创建一个别名 
    // 使用别名 以后可以在这改,就可以轻松实现路由模式的切换
    import {BrowserRouter as RouterSelf}   from  "react-router-dom"
    
    import App from "./App"
    
    const container =document.getElementById("root")
    const root =ReactDom.createRoot(container)
    
    // 用来包裹 App 这个组件即可
    root.render(
        	   <RouterSelf>
                    <App/>
                </RouterSelf>
               )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.2 hash模式

    hash 模式的路由,对应引入的是 HashRouter 组件。

    import React  from "react"
    import ReactDOM  from "react-dom/client"
    
    // 引入路由组件  使用 as 创建一个别名 
    // 使用别名 以后可以在这改,就可以轻松实现路由模式的切换
    import {HashRouter as RouterSelf}   from  "react-router-dom"
    
    import App from "./App"
    
    const container =document.getElementById("root")
    const root =ReactDom.createRoot(container)
    
    // 用来包裹 App 这个组件即可
    root.render(
        	   <RouterSelf>
                    <App/>
                </RouterSelf>
               )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    至于hsitory和hash模式的区别,我在vue路由中写过一篇区分二者的博客:VueRouter — vue路由hash模式和history模式

    三、路由配置

    3.1 配置

    我们使用路由组件包含了App组件,所以应该在App组件中配置路由。
    在这里插入图片描述

    App.jsx

    import  {Routes, Route,Navigate} from "react-router-dom"
    
    import HomePage from "./pages/HomePage";
    import LoginPage from "./pages/LoginPage";
    import HelpPage from "./pages/HelpPage";
    import AboutPage from "./pages/AboutPage";
    
    function  App(){
        return(
            <Routes>
                {/*
    		path 后面书写的是路径
    		element 后面书写的是对应的组件
                */}
                <Route path="/login" element={<LoginPage />}></Route>
                {/*
                	嵌套路由:
                		v6 版本的子路由直接被父路由包裹
                */}
                <Route path="/home"  element={<HomePage />}>
                    {/* 这里书写的就是嵌套的路由*/}
                    <Route path="about" element={<AboutPage />}></Route>
                    <Route path="help" element={<HelpPage />}></Route>
                </Route>
                {/*
                	路由的重定向
                	这里使用的是 Navigate 组件
                	因为路由表的匹配是从上往下匹配的,所以重定向的路由写在最下面
                */}
                <Route path="*" element={<Navigate to="/login" />} ></Route>
            </Routes>
        )
    }
    
    export default App;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    HomePage.jsx:
    在这里插入图片描述
    Link 和 NavLink 都可以实现路由跳转,但是 NavLink 自身存在一个 active的类名,可以在里面设置激活之后的样式。
    在这里插入图片描述
    例如这里,我设置.active类的样式。

    在这里插入图片描述

    3.2 编程式导航

    useNavigate() 函数会返回一个函数,这个函数暂且叫做navigate,名字随意取,navigate用来实现编程导航的跳转。参考vue中的router.push等方法。

    const navigate=useNavigate()  
    
    navigate("/login") // 这种是push的方式
    
    navigate("/login",{replace:true})  // 第二个参数表示路由跳转之后是push进去,还是直接替换之前的组件,replace:true 那么就是替换之前的组件,不会有历史,不能退回到前一步
    
    // 后退一下 下面这个函数的功能就和 History 里面的 go() 函数用法类似
    navigate(-1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.2 默认子路由

    给子route组件设置index属性,那么改路径下就会默认显示该router的element所对应的组件。
    在这里插入图片描述
    此时/home的Outlet默认会显示AboutPage组件,但是不能设置path属性。

    四、路由传参

    4.1 params传参

    需要在定义路由时声明参数名称:

    <Route path="single-blog/:id" element={<SingleBlog/>}></Route>
    
    • 1

    多个参数在后面递加/:paramsName即可。

    跳转时携带参数:

    <NavLink to="/single-blog/123" >博客详情</NavLink>
    
    • 1

    编程式:

    const navigate = useNavigate();
    navigate.push('/single-blog/123')
    
    • 1
    • 2

    组件中获取:

    const parmas = useParams();
    console.log(parmas);//{id: 123}
    
    • 1
    • 2

    页面刷新,参数不会失效。

    4.2 search传参

    不需要在定义路由时声明参数名称,和超链接请求跳转非常相似,使用?和&拼接参数。

    <NavLink to="/single-blog?id=123&&mode='light'" >博客详情</NavLink>
    
    • 1

    编程式:

    const navigate = useNavigate();
    navigate.push("/single-blog?id=123&&mode='light'");
    
    • 1
    • 2

    组件中获取,需要使用useSearchParams:

    const [search]=useSearchParams()
    console.log(search.get('id'));//123
    console.log(search.get('mode'));//light
    
    • 1
    • 2
    • 3

    属性页面,参数不会失效。

    4.3 state传参

    不需要在定义路由时声明参数名称,只需在Link或者NavLink上声明state属性并赋值即可。

    <NavLink to={'/single-blog'} state={{id:123,mode:'light'}}>博客详情</NavLink>
    
    • 1

    编程式:

    const navigate = useNavgate();
     navigate('/single-blog',{
       replace:false,
       state:{
         id: 123,
         mode: 'light'
       }
     })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    组件中获取,需要使用useLocation:

    const {state: {id,mode} } = useLocation();
    console.log(id,mode);//123,light
    
    • 1
    • 2

    五、路由守卫(拦截)

    创建一个路由鉴权组件:
    AuthRoute.jsx

    import { Navigate , useLocation } from "react-router"
    
    export default function AuthRoute({children}) {
      //获取到locationStorage中的token
      const token = localStorage.getItem('token')
    
      //获取location
      const { pathname} = useLocation()
      if(!token){
        return <Navigate to="/login" state={{returnURL:pathname}}></Navigate>
      }
      //如果存在 则渲染标签中的内容
      return children;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    需要鉴权的组件放在AuthRoute标签中:

    <Route path="/profile" element={
    	<AuthRoute>
    		<Profile></Profile>	
    	</AuthRoute>
    }></Route>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    【祝福伟大的祖国】Java Web 9.2 Request 对象 9.2.6 Request 请求转发
    按最少次数开关点亮所有灯
    产品补丁包测试的基本流程
    【MicroPython ESP32】ssd1306模块基于GB2312字库驱动0.96“I2C屏幕汉字显示示例
    Java设计模式 _创建型模式_工厂模式(普通工厂和抽象工厂)
    GIS 分析常用的 7 个地理处理工具
    AspNetCore 成长杂记(一):JWT授权鉴权之生成JWT(其二)
    【C++】智能指针
    [附源码]计算机毕业设计JAVA医疗预约系统
    如何高效填写软件测试缺陷报告?
  • 原文地址:https://blog.csdn.net/ZHANGYANG_1109/article/details/126022959