react基础Day04-React原理揭秘React路由基础

news2024/11/23 7:55:21

React原理揭秘

目标

  • 能够说出React组件的更新机制
  • 能够对组件进行性能优化
  • 能够说出虚拟DOM和DIff算法

组件更新机制

  • setState() 的两个作用

    • 修改state
    • 更新组件
  • 过程:父组件重新渲染时,也会重新渲染子组件,但只会渲染当前组件子树(当前组件以其所有子组件)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDmHrfMg-1673796409983)(images/组件更新.png)]

组件性能优化

减轻state

  • 减轻state:只存储跟组件渲染相关的数据(比如:count/ 列表数据 /loading等)
  • 注意:不用做渲染的数据不要放在state中
  • 对于这种需要在多个方法中用到的数据,应该放到this中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jafo8OTO-1673796409984)(images/减轻state.png)]

避免不必要的重新渲染

  • 组件更新机制:父组件更新会引起子组件也被更新,这种思路很清晰
  • 问题:子组件没有任何变化时也会重新渲染
  • 如果避免不必要的重新渲染?
  • 解决方式:使用钩子函数 shouldComponentUpdate(nextProps, nextState)
    • 在这个函数中,nextProps和nextState是最新的状态以及属性
  • 作用:这个函数有返回值,如果返回true,代表需要重新渲染,如果返回false,代表不需要重新渲染
  • 触发时机:更新阶段的钩子函数,组件重新渲染前执行(shouldComponentUpdate => render)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rndh2dqt-1673796409985)(images/shouldComponentUpdata.png)]

随机数案例

需求:随机生成数字,显示在页面,如果生成的数字与当前显示的数字相同,那么就不需要更新UI,反之更新UI。

利用nextState参数来判断当前组件是否需要更新

class App extends React.Component {
    state = {
        number: 0
    }
    // 点击事件,每次点击生成一个随机数
    hanldeBtn = () => {
        this.setState({
            number: Math.floor(Math.random() * 3)
        })
    }
    // 将要更新UI的时候会执行这个钩子函数
    shouldComponentUpdate(nextProps,nextState) {
         // 判断一下当前生成的 值是否与页面的值相等
         if(nextState.number !== this.state.number){
             return true
         }
         return false
    }
    render() {
        return (
            <div>
                随机数:{this.state.number} <br />
                <button onClick={this.hanldeBtn}>生成随机数</button>
            </div>
        )
    }
}

利用props参数来判断是否需要进行更新

class App extends React.Component {
    state = {
        number: 0
    }
    // 点击事件,每次点击生成一个随机数
    hanldeBtn = () => {
        this.setState({
            number: Math.floor(Math.random() * 3)
        })
    }

    render() {
        return (
            <div>
                <NumberBox number={this.state.number} />
                <button onClick={this.hanldeBtn}>生成随机数</button>
            </div>
        )
    }
}
class NumberBox extends React.Component {
    // 将要更新UI的时候会执行这个钩子函数
    shouldComponentUpdate(nextProps, nextState) {
        // 判断一下当前生成的 值是否与页面的值相等
        if (nextProps.number !== this.props.number) {
            return true
        }
        return false
    }
    render() {
        return (
            <h1>随机数:{this.props.number} </h1>
        )
    }
}

纯组件

作用以及使用

  • 纯组件: PureComponent 与 React.Component 功能相似
  • 区别: PureComponent 内部自动实现了 shouldComponentUpdate钩子,不需要手动比较
  • 原理:纯组件内部通过分别比对前后两次 props和state的值,来决定是否重新渲染组件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qzBzyhxn-1673796409986)(images/PureComponent.png)]

实现原理

  • 说明:纯组件内部的对比是 shallow compare(浅层对比)
  • 对于值类型来说:比较两个值是否相同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q765BDm1-1673796409986)(images/值类型比对.png)]

  • 引用类型:只比对对象的引用地址是否相同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0HvWoLp-1673796409986)(images/引用类型比对.png)]

  • 注意:state 或 props 中属性值为引用类型时,应该创建新数据,不要直接修改原数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NXJ3hZaf-1673796409987)(images/注意点.png)]

虚拟DOM和Diff算法

  • React更新视图的思想是:只要state变化就重新渲染视图
  • 特点:思路非常清晰
  • 问题:组件中只有一个DOM元素需要更新时,也得把整个组件的内容重新渲染吗? 不是这样的
  • 理想状态:部分更新,只更新变化的地方
  • React运用的核心点就是 虚拟DOM 配合 Diff 算法

虚拟DOM

本质上就是一个JS对象,用来描述你希望在屏幕上看到的内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zl8bF6cM-1673796409988)(images/虚拟DOM.png)]

Diff算法

执行过程

  • 初次渲染时,React会根据初始化的state(model),创建一个虚拟DOM对象(树)
  • 根据虚拟DOM生成真正的DOM,渲染到页面
  • 当数据变化后(setState()),会重新根据新的数据,创建新的虚拟DOM对象(树)
  • 与上一次得到的虚拟DOM对象,使用Diff算法比对(找不同),得到需要更新的内容
  • 最终,React只将变化的内容更新(patch)到DOM中,重新渲染到页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hU3aH3QX-1673796409988)(images/diff算法.png)]

代码演示

  • 组件render()调用后,根据状态和JSX结构生成虚拟DOM对象(render()方法的调用并不意味着浏览器进行渲染,render方法调用时意味着Diff算法开始比对了)
  • 示例中,只更新p元素的文本节点内容
  • 初次渲染的DOM对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T9U3Oxvy-1673796409989)(images/初次的虚拟DOM对象.png)]

  • 数据更新之后的虚拟DOM对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBFZgnwM-1673796409989)(images/更新后的虚拟DOM对象.png)]

小结

  • 工作角度:应用第一,原理第二
  • 原理有助于更好的理解React的自身运行机制
  • setState() 异步更新数据
  • 父组件更新导致子组件更新,纯组件提升性能
  • 思路清晰简单为前提,虚拟DOM和Diff保效率(渲染变化的组件)
  • 虚拟DOM -> state + JSX
  • 虚拟DOM最大的特点是 脱离了浏览器的束缚,也就是意味着只要是能支持js的地方都可以用到react,所以为什么说react是可以进行跨平台的开发

React路由基础

目标

  • 能够说出React路由的作用
  • 能够掌握-react-router-dom的基本使用
  • 能够使用编程式导航跳转路由
  • 能够知道React路由的匹配模式

React路由介绍

现代的前端应用大多数是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器压力更小,所以更受欢迎。为了有效的使用单个页面来管理多页面的功能,前端路由应运而生。

  • 前端路由功能:让用户从一个视图(页面)导航到另一个视图(页面)
  • 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系
  • 使用React路由简单来说,就是配置路径和组件

路由的基本使用

使用步骤

  • 安装: yarn add react-router-dom

    • 如果没有安装yarn工具的,需要先全局安装一下yarn:npm install -g yarn
  • 导入路由的三个核心组件: Router / Route / Link

    import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
    
  • 使用Router 组件包裹整个应用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MYsO8A3f-1673796409989)(images/Router.png)]

  • 使用Link组件作为导航菜单(路由入口)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JjFBZPrR-1673796409990)(images/link入口.png)]

  • 使用Route组件配置路由规则和要展示的组件(路由出口)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3HgLqpmn-1673796409990)(images/route.png)]

常用组件说明

  • **Router组件:**包裹整个应用,一个React应用只需要使用一次
    • 两种常用的Router: HashRouter和BrowserRouter
    • HashRouter: 使用URL的哈希值实现 (localhost:3000/#/first)
    • 推荐 BrowserRouter:使用H5的history API实现(localhost3000/first)
  • **Link组件:**用于指定导航链接(a标签)
    • 最终Link会编译成a标签,而to属性会被编译成 a标签的href属性
  • **Route组件:**指定路由展示组件相关信息
    • path属性:路由规则,这里需要跟Link组件里面to属性的值一致
    • component属性:展示的组件
    • Route写在哪,渲染出来的组件就在哪

路由的执行过程

  • 当我们点击Link组件的时候,修改了浏览器地址栏中的url
  • React路由监听地址栏url的变化
  • React路由内部遍历所有的Route组件,拿着Route里面path规则与pathname进行匹配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wm6TrEfY-1673796409991)(images/route匹配.png)]

  • 当路由规则(path)能够匹配地址栏中的pathname时,就展示该Route组件的内容

编程式导航

  • **场景:**点击登陆按钮,登陆成功后,通过代码跳转到后台首页,如何实现?
  • **编程式导航:**通过JS代码来实现页面跳转
  • history是React路由提供的,用于获取浏览器历史记录的相关信息
  • **push(path):**跳转到某个页面,参数path表示要跳转的路径
  • go(n):前进或后退功能,参数n表示前进或后退页面数量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rYVDUlan-1673796409992)(images/编程式导航.png)]

默认路由

  • 现在的路由都是通过点击导航菜单后展示的,如果进入页面的时候就主动触发路由呢
  • 默认路由:表示进入页面时就会匹配的路由
  • 默认路由:只需要把path设置为 '/'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5q5WAMeT-1673796409992)(images/默认路由.png)]

匹配模式

模糊匹配模式

  • 当Link组件的to属性值为 ‘/login’ 时候,为什么默认路由也被匹配成功?
  • 默认情况下,React路由是模糊匹配模式
  • 模糊匹配规则:只要pathname以path开头就会匹配成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YI2x7XXP-1673796409993)(images/模糊匹配模式.png)]

精准匹配

  • 默认路由认可情况下都会展示,如果避免这种问题?
  • 给Route组件添加exact属性,让其变为精准匹配模式
  • 精确匹配:只有当path和pathname完全匹配时才会展示改路由

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DWVfVVTW-1673796409993)(images/精确匹配.png)]

小结

  • React路由可以有效的管理多个视图实现 SPA
  • 路由先需要通过安装
  • Router组件包裹整个应用,只需要使用一次
  • Link组件是入口,Route组件是出口
  • 通过props.history实现编程式导航
  • 默认是模糊匹配,添加exact编程精确匹配
  • React路由的一切都是组件,可以像思考组件一样思考路由

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/165609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Android Studio]查看和修改Android API SDK的配置

&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Android Debug&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Topic 发布安卓学习过程中遇到问题解决过程&#xff0c;希望我的解决方案可以对小伙伴们有帮助。 &#x1f4cb;笔记目…

高并发系统设计 -- 缓存与数据库一致性问题详细讲解

CAP理论 首先来谈一下数据的一致性这个话题&#xff0c;所谓的一致性就是数据保持一致&#xff0c;在分布式系统中&#xff0c;可以理解为多个节点中的数据的值是一致的。 强一致性&#xff1a;这种一致性级别是最符合用户直觉的&#xff0c;它要求系统写入什么&#xff0c;读…

steam搬砖项目,信息差赚钱,内含全部讲解

Steam平台就是一个全球的游戏平台&#xff0c;搬砖主要是搬的一款火遍全球的游戏CSGO的装备和饰品。CS听说过吧&#xff0c;这款游戏就是CS的一个系列。&#xff08;通俗易懂的理解就是&#xff0c;从国外steam游戏平台购买装备&#xff0c;再挂到国内网易buff平台上进行售卖。…

【TypeScript】TS进阶-装饰器(九)

&#x1f431;个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️作者简介&#xff1a;前端领域新星创作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff1a;vue3从入门到…

ADI demo PL工程的编译-以adrv9371x_zc706为例子之使用Cygwin

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ADI demo PL工程的编译-以adrv9371x_zc706为例子之使用Cygwin前言Cygwin 安装工程编译总结前言 之前一篇ADI demo工程的编译是ADI不推荐的方法&#xff0c;而且确实在后面NO…

【Django项目开发】django的信号机制(八)

文章目录1、什么是信号2、代码实现3、要想上面定义的信号机制生效,需要在apps.py中加载信号机制1、什么是信号 通俗来说,信号就是通信双方约定的一种信息通知方式,双方通过信号来确定发生了什么事情,然后决定自己应该做什么。 Django 中的信号用于在框架执行操作时解耦。当某…

2.1总线概述

文章目录一、总线简图二、概念与分类1.总线定义2.总线特点&#xff08;1&#xff09;分时&#xff08;2&#xff09;共享3.总线特性4.总线的分类&#xff08;1&#xff09;按数据传输格式①串行总线②并行总线&#xff08;2&#xff09;按总线功能①片内总线②系统总线③通信总…

【原创】linux实时应用如何printf输出不影响实时性?

linux实时应用printf输出 文章目录linux实时应用printf输出1. 前言2. linux终端输出3. 常见的NRT IO输出方案3.1 一种实现方式3.3 改进3. Xenomai3 printf()接口3.1 应用运行前环境初始化1. GCC特定语法2. libcobalt printf初始化流程3.2 libcobalt printf内存管理1. print_buf…

我的周刊(第074期)

我的信息周刊&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。&#x1f3af; 项目code-server[1]这是一款开源的基于 VSCode 的在线编…

【Linux系统】第四篇:Linux中编辑器vim的使用

文章目录一、vim的介绍1、vim的基本模式2、vim的使用二、命令模式1、光标移动操作2、文本复制、粘贴、剪切、撤销操作3、文本编辑相关操作三、插入模式四、底行模式底行模式命令集五、vim的配置原理六、sudo无法提权问题一、vim的介绍 vim是Linux下的一款多模式编辑器。 注意…

【已解决】右键以某应用打开xx文件时,没有“始终”选项怎么办

问题解决方案简单来说详细操作解释问题 右键以某应用打开xx文件时&#xff0c;没有“始终”选项 解决方案 简单来说 在注册表&#xff1a;计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\找到要打开的文件后缀名&#xff0c;删除…

2022尚硅谷SSM框架跟学(五)Spring基础二

2022尚硅谷SSM框架跟学 五Spring基础二3.AOP3.1场景模拟3.1.1声明接口3.1.2创建实现类3.1.3创建带日志功能的实现类3.1.4提出问题(1)现有代码缺陷(2)解决思路(3)困难3.2代理模式3.2.1概念(1)介绍(2)生活中的代理(3)相关术语3.2.2静态代理3.2.3动态代理3.2.4测试3.3AOP概念及相关…

视频 | 生信 linux 实战题目讲解03

点击阅读原文跳转完整教案。1 Linux初探&#xff0c;打开新世界的大门1.1 Linux系统简介和目录理解1.1.1 为什么要用Linux系统1.1.2 Linux系统无处不在1.1.3 免费的Linux系统来一套1.1.4 Linux系统登录-联系远方的她1.1.5 初识Linux系统 - 黑夜中的闪烁是你的落脚点1.1.6 我的电…

使用混沌和非线性控制参数来提高哈里斯鹰优化算法的优化性能,解决车联网相关的路由问题(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

华为路由汇总实验

目录 OSPF路由聚合实验 在ABR上做路由聚合 在ASBR上做路由聚合 BGP路由聚合实验 在AR4-1上做静态聚合 在AR6-3上做手动聚合 ISIS路由聚合实验 R1配置路由聚合 OSPF路由聚合实验 OSPF——基本概念5&#xff08;汇总、更新、认证&#xff09;_静下心来敲木鱼的博客-CSDN博…

华为MPLS单域实验配置

目录 配置AS内的MPLS LDP协议 配置PE-PE之间的MP-BGP协议 在PE上配置VPN实例 在CE侧配置PE-CE的路由协议 在PE侧配置PE-CE的路由协议 在PE侧将CE的路由重发布进MP-BGP中 在CE侧将MP-BGP的路由重发布进CE中 MPLS隧道——单域基础理论讲解_静下心来敲木鱼的博客-CSDN博客h…

SPSS常用的10种统计分析

目录 实验一 地理数据的统计处理 一、实验目的 二、实验内容 三、实验步骤 实验二 双变量相关分析 一、实验目的 二、实验内容 三、实验步骤 实验三 主成分分析 一、实验目的 二、实验内容 三、实验步骤 实验四 因子分析 一、实验目的 二、实验内容 三、实…

【Linux】缓冲区 进度条小程序

目录 一、\r && \n 二、缓冲区的概念 三、小程序编写 1、倒数小程序 2、进度条小程序 一、\r && \n C语言中有很多字符&#xff0c;但是宏观上可以分成两类&#xff1a;可显字符、控制字符。 可显字符包括我们见到的 1、2、3....&#xff0c;a、b、c....…

历史最全事件抽取任务分类、经典论文、模型及数据集整理分享

事件抽取技术是从非结构化信息中抽取出用户感兴趣的事件&#xff0c;并以结构化呈现给用户。事件抽取任务可分解为4个子任务: 触发词识别、事件类型分类、论元识别和角色分类任务。其中&#xff0c;触发词识别和事件类型分类可合并成事件识别任务。事件识别判断句子中的每个单词…

Linux面试题

Linux 概述 什么是Linux Linux是一套免费使用和自由传播的类Unix操作系统&#xff0c;是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想…