【React】setState原理,SCU,不可变对象,Ref,受控组件,高阶组件,封装轮播图组件

news2024/10/6 10:32:15

❤️ Author: 老九
☕️ 个人博客:老九的CSDN博客
🙏 个人名言:不可控之事 乐观面对
😍 系列专栏:

文章目录

  • setState原理
    • setState异步更新
  • SCU
  • 不可变对象
  • Ref
    • Ref获取DOM
    • Ref获取组件
  • 非受控组件
  • 受控组件
  • 高阶组件(HOC)
    • 作用一:进行函数增强功能
    • 作用二:鉴权登录
  • Portals
  • React严格模式
  • 封装轮播图组件

setState原理

  • react没有做数据劫持,需要调用setState告诉react数据发生改变了,之后再调用render函数进行页面更新
  • 我们修改了state之后,希望React根据最新的State来重新渲染界面,但是这种方式的修改React并不知道数据发生了变化,React并没有实现类似于Vue2中的Object.defineProperty或者Vue3中的Proxy的方式来监听数据的变化,我们必须通过setState来告知React数据已经发生了变化

setState异步更新

  • setState的基本使用就是首先通过Object.assign将新数据替换掉原数据,之后在合适的位置重新调用render函数刷新页面
    在这里插入图片描述
  • 第二种写法是里面写一个箭头函数,返回一个对象,这样写有好处1:里面是一个回调函数,在里面可以写一些函数逻辑;好处2:当前的回调函数会将之前的state和props传递进来
    在这里插入图片描述
  • setState在React的事件处理中是一个异步调用,异步调用:并不会阻塞接下来代码的执行,操作并不会立刻完成,而是经过一些时间之后才会完成;如果希望数据更新之后立刻获取数据更新后的参数,可以在setState中传入第二个参数,callback函数
    在这里插入图片描述
  • 为什么setState设计为异步?
  • setState设计为异步在GItHub的issue上个也有很多的讨论,Redux的作者也有对应的回复,我看完之后主要是由这两个问题
    第一可以显著的提升性能,如果每次调用setState都进行一次更新,那么意味着render函数会被频繁调用,界面重新渲染,这样效率是很低的,最好的办法是获取到多个更新,之后进行批量更新
    第二如果我们同步更新state,但是还没有执行render函数的时候,那么state的值和props里面的值就不能保持同步,在开发中会产生很多问题
  • 那么setState一定是异步吗?在这里插入图片描述
    在React18之前,这样写是同步代码(或者直接写DOM原生的click操作),在React18之后,就算是setTimeout中setState也是异步操作,进行批量处理,如果要在18之后做同步处理,在React-dom包中,有一个flushSync函数,里面传一个回调函数写setState即可
    在这里插入图片描述

SCU

  • diff算法更新:同层结点之间相互比较,不会跨节点比较;不同类型的节点,产生不同的树结构,开发中可以通过key来指定哪些节点在不同的渲染下保持稳定
  • 在react中,如果父组件的renden函数调用了,那么子组件的所有render函数也会调用,事实上很多组件没有必须要重新render,如果想让子组件中render不想更新,通过生命周期中shouldComponentUpdate方法
  • 该方法有两个参数
    在这里插入图片描述
    在这里插入图片描述
  • 如果当前组件是一个类组件,React提供了一个PureComponent;如果所有的类,我们都需要手动实现shouldComponentUpdate,那么会给我们开发者增加非常多的工作量,因此提供了一个pureComponenetUpdate
    在这里插入图片描述
  • 但是如果是一个函数组件,我们可以通过memo进行调用,通过判断props有没有改变来决定是否更新render函数
    在这里插入图片描述

不可变对象

  • 如果想在state中的对象添加一个元素,需要创建一个新的对象覆盖原对象,而不是直接修改原对象
    在这里插入图片描述
    在这里插入图片描述

Ref

Ref获取DOM

  • 在React包中引入createRef,然后在constructor中创建ref,在元素上写一个ref属性,之后通过current获取值
    在这里插入图片描述

Ref获取组件

  • 通过forwardRef包裹函数,然后通过ref传递获取
    在这里插入图片描述

非受控组件

  • 通过ref获取值,表单中的元素没有写value值,与state数据无关
    在这里插入图片描述

受控组件

  • 一般input默认是非受控组件,只有我们可以动态修改值之后才是受控组件,如果input有默认值,我们通过输入框是无法修改值的,也就是所谓的非受控,当我们添加了onChange事件之后,可以修改值了,就变成受控组件了。类似于v-model
  • 如果input类型是checkbox,值是checked,事件是onChange

-
在这里插入图片描述

  • 如果是select的多选,需要这么写
    在这里插入图片描述

高阶组件(HOC)

  • 高阶组件是参数为组件,返回值为新组件的函数
  • 利用高阶组件就是对某个组件进行了封装,包裹之后加了一些通用功能
    在这里插入图片描述

作用一:进行函数增强功能

在这里插入图片描述

作用二:鉴权登录

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

Portals

  • 某些情况下,我们希望渲染的内容独立于父组件,甚至独立于当前改在到DOM元素中(默认都是挂载到id为root的DOM元素上)
    在这里插入图片描述在这里插入图片描述

React严格模式

  • StrictMode是一个组件,为其后代的元素触发额外的检查和警告

1.使用不安全生命周期会报警告
在这里插入图片描述

2.使用不安全的ref会报警告
在这里插入图片描述
3.检查意外的副作用
设置严格模式之后,这个组件的constructor会被调用两次,这是严格模式下故意进行的操作,让你来查看在这里写的一些逻辑代码被调用多次时,是否会产生一些副作用,在生产环境中,是不会被调用两次的
4.会检测过时的context API,早期Context是通过static属性声明Context对象,通过getChildContext返回Context对象等方式使用Context,目前这种方法已经不推荐使用了

封装轮播图组件

import { Component, ReactNode } from 'react'

type Props = {
  imgs: string[],
  buttons?: boolean,
  indicators?: boolean,
  autoplay?:number,
  onChange?:(index:number)=>void,
}

type State = {
  currentIndex:number,
}

class Slider extends Component<Props,State> {
  static defaultProps = {
    buttons: true,
    indicators: true,
    autoplay: 0,
    onChange : () => {},
  }
  id: number | NodeJS.Timer = 0;
  constructor(props : Props) {
    super(props)
    this.state = {
      currentIndex: 0,

    }
  }

  prev = () =>{
    this.setState({
      currentIndex: this.state.currentIndex - 1
    }, () => {
      this.props.onChange!(this.state.currentIndex)
     })
    if (this.state.currentIndex === 0) {
      this.setState({
        currentIndex: this.props.imgs.length-1
      }, () => {
        this.props.onChange!(this.state.currentIndex)
       })
    }
  }

  next = () => {
    this.setState({
      currentIndex: this.state.currentIndex + 1
    }, () => {
     this.props.onChange!(this.state.currentIndex)
    })
    if (this.state.currentIndex === this.props.imgs.length -1) {
      this.setState({
        currentIndex: 0
      }, () => {
        this.props.onChange!(this.state.currentIndex)
       })
    }
  }

  componentDidMount(): void {
    if (this.props.autoplay! > 0) {
     this.id = setInterval(() => {
        this.next()
      },this.props.autoplay)
     }
  }

  componentWillUnmount(): void {
     clearInterval(this.id)
  }

  render(): ReactNode {
    return (
      <div>
        <img src={ this.props.imgs[this.state.currentIndex] } />
        <button onClick={this.prev}>&lt;</button>
        <button onClick={this.next}>&gt;</button>
        <ul>
          {
            this.props.imgs.map((img,index) => {
              return <li key={index} onClick={()=>this.setState({currentIndex:index})}>{index}</li>
            })
          }
        </ul>
      </div>
    )
  }
}

export default Slider


在这里插入图片描述

————————————————————————
♥♥♥码字不易,大家的支持就是我坚持下去的动力♥♥♥
版权声明:本文为CSDN博主「亚太地区百大最帅面孔第101名」的原创文章

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

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

相关文章

word目录怎么自动生成,3个步骤轻松搞定!

案例&#xff1a;我在做策划案的时候&#xff0c;需要制作目录。我觉得自己手动制作目录很困难&#xff0c;通过word的可以自动生成目录&#xff0c;但是我不知道具体的操作方法。有没有小伙伴可以分享一下&#xff1f; 在制作任务书、书写论文的时候&#xff0c;经常需要添加…

vue+java+springboot企业办公人事oa办公管理系统2142g

本企业OA管理系统有管理员和用户。管理员功能有个人中心&#xff0c;用户管理&#xff0c;公告信息管理&#xff0c;客户关系管理&#xff0c;通讯录管理&#xff0c;日程安排管理&#xff0c;车辆信息管理&#xff0c;文件信息管理&#xff0c;工作日志管理&#xff0c;上班考…

0基础学习VR全景平台篇第42篇:编辑器底部菜单-分组管理

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;底部菜单—分组管理功能操作。 功能位置示意 一、本功能将用在哪里&#xff1f; 分组管理&#xff0c;指观看者可点击不同分组&#xff0c;查看不同类型全景内容…

learn C++ NO.9——string(2)

引言&#xff1a; 现在是北京时间的2023年6月15日早上的10点14分。时间过得飞快&#xff0c;现在已经大一的最后一个星期了。明天也是大一最后一次课&#xff0c;线下的实训课。线下实训内容为c语言二级的内容&#xff0c;对我来说跟学校的课效率太低下了&#xff0c;我还是比…

初识网络之再看udp协议

目录 一、端口号 1. 五元组 2. 端口号范围划分 3. 一些知名端口号 4. 进程与端口号 5. 两个常用网络工具 5.1 netstat 5.2 pidof 二、UDP协议 1. udp协议格式 2. udp报文解包 3. udp报文分用 4. udp的特点 5. 缓冲区 5.1 tcp缓冲区 5.2 udp缓冲区 6. 一些常见…

函数重载异常的常见原因

函数重载异常的常见原因 使用重载函数时&#xff0c;如果数据类型不匹配&#xff0c;C尝试使用类型转换与形参进行匹配&#xff0c;如果转换后有多个函数能匹配上&#xff0c;编译将报错。引用可以作为函数重载的条件&#xff0c;但是&#xff0c;调用重载函数的时候&#xff0…

Linux:端口

端口是设备与外界进行通讯的出入口&#xff0c;端口可以分为物理端口和虚拟端口 物理端口&#xff1a;又叫接口&#xff0c;是可见的端口&#xff0c;比如HDMI端口、USB接口虚拟端口&#xff1a;是指计算机内部的端口&#xff0c;用来操作系统和外部进行交互使用 通过IP地址只能…

6.python高频函数-处理缺失值isnull()、fillna()、dropna()

前言 如何判断pandas.DataFrame、Series是否包含缺失值NaN以及如何处理缺失值NaN。 Part.1 isnull() 函数 使用 isnull()、isna() 确定每个元素的缺失值 如果值为 NaN&#xff0c;则值为 True&#xff0c;如果不是&#xff0c;则值为 False。 读取数据集 panel_data pd.r…

从C语言到C++_19(容器适配器+stack和queue模拟实现+优先级队列priority_queue)

目录 1. 容器适配器 1.1 什么是适配器 1.2 STL标准库中stack和queue的底层结构 2. stack和queue的模拟实现 2.1 stack模拟实现 2.2 queue的模拟实现 3. deque的介绍(了解) 3.1 deque的实现原理 3.2 deque的缺陷和使用场景 4. 优先级队列 priority_queue 4.1 priorit…

编码规范、Git分支整理

代码命名规范 包命名规范 采用反域名命名规则&#xff0c;全部使用小写字母。一级包名为com&#xff0c;二级包名kl&#xff08;为公司名称&#xff0c;可以简写&#xff09;&#xff0c;三级包名pos&#xff08;根据应用进行命名&#xff09;&#xff0c;四级包名activity或…

芳禾数据CTO李明:数据分类分级与治理驱动下的应用革命丨数据猿专访

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 我们进入数字化时代&#xff0c;数据已经变得比任何时候都更加关键。每天&#xff0c;我们都在生成、处理和存储海量的数据&#xff0c;这些数据在企业决策、市场研究、产品开发等方面扮演着重要的角色。然而&#xff0c;数…

Qt编写精美输入法(历时十年迭代/可换肤/支持Qt4/5/6/win/linux/mac/嵌入式等)

一、前言 大概是从2012年就开始研究用Qt写输入法&#xff0c;因为项目需要&#xff0c;嵌入式板子上&#xff0c;没有对应的输入法&#xff0c;当初使用过很多NVR&#xff0c;里面也是鼠标按下弹出输入法面板进行输入&#xff0c;可以切换数字和字母及中文&#xff0c;于是借鉴…

5大趋势与10大应用场景!未来的智能工厂要这么建...

在经济下行压力、人口红利消失、消费结构升级、疫情冲击等多种因素推动下&#xff0c;制造企业加快转型步伐&#xff0c;工厂正向高效化、智能化、绿色化方向跃迁升级&#xff0c;不断涌现出技术创新、应用领先、成效显著的智能工厂。 近日&#xff0c;中国信息通信研究院发布…

常见的台账在线、可视化数据看板工具

目前已知和常见的一些在线可视化数据看板工具&#xff1a; Trello&#xff1a;Trello 是一种流行且直观的看板工具&#xff0c;可让创建看板、列表和卡片来管理任务和项目。它提供了一个可视化界面&#xff0c;可以在其中跨工作流程的不同阶段拖放卡片。还可以添加截止日期、标…

cesium调用celestrak接口获取卫星数据

celestrak是一家免费开源提供卫星空间数据的非营利性组织 接口调用 import axios from "axios";const BASE_URL "https://celestrak.org";function getTleDataFromExternal(path "") {let uri ${BASE_URL}/NORAD/elements/gp.php?GROUP${…

复习并发编程的基础知识之线程池

并发编程中&#xff0c;线程池是很重要的一块内容。 线程池是一种池化技术&#xff0c;线程池、字符串常量池和数据库链接池都属于池化技术。 使用线程池的好处&#xff1a; 1.提高了线程的利用率&#xff08;想一想&#xff0c;我们不可能每打一个电话&#xff0c;就去买一部手…

Unity编辑器扩展-第三集-添加按钮到组件菜单并且重置组件

第二集链接&#xff1a;Unity编辑器扩展-第二集-按钮排序/分组/放入右键菜单_菌菌巧乐兹的博客-CSDN博客 一、本节目标效果展示 1.把按钮放到组件菜单上 2.做一个类似Reset功能&#xff0c;点一下能改变里面的数据 二、 把按钮放到组件菜单上 如上图&#xff0c;我的的组件名…

echarts 配置相关

echarts更多模板链接 http://chart.majh.top/ 1、echarts.clear()是清空当前实例&#xff0c;会移除实例中所有的组件和图表。 echarts.dispose()是销毁实例&#xff0c;销毁后实例无法再被使用。 this.chart.dispose() this.chart.clear(); // 清空图表2、series虽然是[] 数…

BRC20赛道的刚需基础设施,BrccSwap如何延续新的造富神话?

引言 BRC20代币和去中心化交易所的背景 BRC20代币赛道的刚需SWAP BrccSwap如何延续新的造富神话 结语 引言 随着加密货币市场的不断发展&#xff0c;BRC20代币和去中心化交易所成为了越来越受欢迎的概念。BRC20代币是建立在比特币区块链上的代币&#xff0c;具有高级别的…

一季度亏损47亿,全系降价背后,蔚来能否实现自救?

降价之后&#xff0c;蔚来能否实现自救&#xff1f; 6月12日&#xff0c;蔚来汽车宣布全系车型起售价减 3 万元&#xff1b;新购车首任车主用车权益调整为整车6年或15万公里质保等&#xff1b;免费换电补能不再作为标准用车权益&#xff0c;新用户可灵活选择在家充电或到充换电…