setState的使用+React更新机制+events+受控和非受控组件

news2024/12/25 9:13:42

setState是异步更新
总结:
1.setState设计为异步,可以显著的提升性能

  • 如果每次调用 setState都进行一次更新,那么意味着render函数会被频繁调用,界面重新染,这样效率是很低的;
  • 最好的办法应该是获取到多个更新,之后进行批量更新;
    2.如果同步更新了state,但是还没有执行render函数,那么state和props不能保持同步;
  • state和props不能保持一致性,会在开发中产生很多的问题;

如何获取state的结果

import React, { Component } from 'react'

export default class anli extends Component {
  constructor(props){
    super(props);
    this.state={
      counter:0,
      message:'hi'
    }

  }
  render() {
    return (
      <div>
        <button onClick={e=>this.increment()}>改字段</button>
        <h2>{this.state.message}</h2>
      </div>
    )
  }
  componentDidUpdate(){
    // 方式二:获取异步更新的state
    console.log(this.state.message)
  }

  increment(){
    //方式一:获取异步更新后的数据
    // setState(更新的state,回调函数)
    this.setState({
      message:'hello'
    },()=>{
      console.log('message',this.state.message)
    })

  }
}

同步更新setState
说明一下,我测试的并不是这样,还是异步。我目前还未找到原因
在这里插入图片描述
setState合并时进行累加

this.setState((prevState,props)=>{
	return {
		counter:preState.counter+1
	}
})

React更新机制

在这里插入图片描述
React在props或state发生改变时,会调用React的render方法,会创建一颗不同的树

react性能优化

  • 列表中keys的作用
  • 组件嵌套的render调用

key的注意事项

  • key应该是唯一的
  • key不要使用随机数(随机数在下一次render时,会重新生成一个数字)
  • 使用index作为key,对性能是没有优化的

shouldComponentUpdate 用法

  shouldComponentUpdate(nextProps,nextState){
    // 返回true,调用render方法。返回false,不调用remder方法
    if(this.state.counter !== nextState.counter){
      return true
    }
    return false;
  }

render 只想改变一次 ,继承pureComponent(不能解决函数式再次渲染)

函数组件使用memo

import React, { Component, PureComponent,memo } from 'react'
// Header
const MemoHeader = memo(
  function Header(){
    console.log('Header 被调用了')
    return <h2>我是header组件</h2>
  }
)

// Main
class Main extends Component{
  render(){
    console.log('main 被调用')
    return <h3>我是main组件</h3>
  }
}

// banner
class Banner extends PureComponent{
  render(){
    console.log('banner 被调用')
    return <h3>我是banner组件</h3>
  }
}

export default class anli extends PureComponent {
  constructor(props){
    super(props);
    this.state={
      counter:0,
      message:'hi'
    }

  }
  render() {
    console.log('APP render函数被调用')
    return (
      <div>
        <MemoHeader></MemoHeader>
        <Banner></Banner>
        <Main></Main>
        <h2>当前计数:{this.state.counter}</h2>
        <button onClick={e=>this.changeText()}>改文本</button>
        <button onClick={e=>this.increment()}>改文本</button>        
      </div>
    )
  }


  changeText(){
    this.setState({
      message:'hello0'
    });
  }

  increment(){
    this.setState({
      counter:this.state.counter+1
    })
  }
}


问题:

  • 全局事件传递events
  • setState传递的数据需要是不可变的数据

setState不可变

insertData(){
	const newFriends = [...this.state.friends];
	newFriends.push[{name:'tom',age:20}]
	this.setState({
		friends:newFriends
	})
	
}

全局事件传递

安装events

yarn add events
import React, { PureComponent } from 'react'
import {EventEmitter} from 'events'
// 事件总线:event bus
const eventBus = new EventEmitter();

class Home extends PureComponent{
  // 添加事件监听
  componentDidMount(){
    eventBus.addListener('sayHello',this.handleSayHelloListener)
  }

  // 取消事件监听
  componentWillUnmount(){
    // 取消所有的sayhello事件
    eventBus.removeListener('sayHello',this.handleSayHelloListener)
  }

  handleSayHelloListener(num,message){
    console.log(num,message)
  }
  render(){
    return (
      <div>
        Home
      </div>
    )
  }
}

class Profile extends PureComponent{
  render() {
    return (
      <div>
        Profile
        <button onClick={e=>this.emmitEvent()}>点击Profile</button>
      </div>
    )
  }

  emmitEvent(){
    eventBus.emit('sayHello','hello home',123)
  }
}

export default class anli extends PureComponent {
  render() {
    return (
      <div>
        <Home />
        <Profile />
      </div>
    )
  }
}

受控和非受控组件

1.如何使用ref

创建refs来获取对应的DOM。

import React, { PureComponent,createRef } from 'react'

export default class anli extends PureComponent {

  constructor(props){
    super(props);
    
    this.titleRef = createRef();
    this.titleEl = null
  }

  render() {
    return (
      <div>
        {/* ref=字符串/对象/函数 */}
        <h2 ref='titleRef'>hello</h2>
        {/* 目前react推荐的方式 */}
        <h2 ref={this.titleRef}>react</h2>

        <h2 ref={(arg)=>{this.titleEl=arg}}>hello</h2>
        <button onClick={e=>this.changeText()}>改变文本</button>
      </div>
    )
  }

  changeText(){
    // 1. 使用方式一:字符串(不推荐)
   this.refs.titleRef.innerHTML = 'react'
   // 2.使用方式二:对象方式
   this.titleRef.current.innerHTML = 'hello javascript'
   //3.回调函数方式
    this.titleEl.innerHTML='functiona'
  }
}

受控组件
我的理解就是 表单,双向绑定

import React, { PureComponent } from 'react'

export default class anli extends PureComponent {
  constructor(props){
    super(props);
    this.state = {
      username:'',
      password:'',
      vaild:''
    }
  }

  render() {
    return (
      <div>
        <form onSubmit={e=>this.handleSubmit(e)}>
          <label htmlFor="username">
            用户:
            <input type="text" 
                   id='username'  
                   name='username'
                   value={this.state.username}
                  onChange={e=>this.handleChange(e)}/>
          </label>
          <label htmlFor="password">
            密码:
            <input type="text" 
                   id='password'  
                   name='password'
                   value={this.state.password}
                  onChange={e=>this.handleChange(e)}/>
          </label>
          <label htmlFor="vaild">
            验证:
            <input type="text"   
                   id='vaild'  
                   name='vaild'
                   value={this.state.vaild}
                  onChange={e=>this.handleChange(e)}/>
          </label>
          <input type="submit" value='提交' />
        </form>
      </div>
    )
  }
  handleSubmit(event){
    // 取消默认行为
    event.preventDefault();
  }

  handleChange(event){
    this.setState({
      // 计算属性名
      [event.target.name]:event.target.value
    })
  }
}


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

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

相关文章

单片机开发---ESP32S3移植lvgl+触摸屏

书接上文 《单片机开发—ESP32-S3模块上手》 本章内容 熟悉一下ESP32S3的开发&#xff0c;修改范例程序的lvgl&#xff0c;使之能够匹配现在的显示屏。 具体工作大概为通过SPI接口连接一块SPI串口屏幕&#xff0c;并且适配lvgl&#xff0c;最后加上触摸屏作为输入。 屏幕 …

【计算机网络】第一章 计算机网络结构

文章目录第一章 体系结构1.1 计算机网络概述1.1.1 计算机网络的概念1.1.2 计算机网络的组成1.1.3 计算机网络的功能1.1.4 计算机网络的分类*1.1.5 计算机网络的标准化工作1.1.6 计算机网络的性能指标1.2 计算机网络体系结构与参考模型1.2.1 计算机网络分层结构1.2.2 计算机网络…

#8链表的中间结点#

链表的中间结点 1题目链接 链接 2思路 思路1:遍历一遍 计数 然后/2 再遍历一遍 思路2:slow fast指针 slow指针一次走1步 fast指针一次走2步 当fast为空的时候 slow的位置就是中间结点 奇数个: 1 2 3 4 5 fast走完第三次为空 slow走完第三次就是3 偶数个: 1 2 3 4 5 6 fast走完…

智慧型物业管理系统功能解析

随着当前社会经济的发展与科技发达&#xff0c;物业管理系统化已经成为常态了。尤其是随着智慧物业管理系统功能越来越多&#xff0c;人们对智慧物业管理系统的依赖就更明显了。毕竟系统真的可以给生活带来很多的便利之处&#xff1a; 业主可通过该系统查询自己住房的详细信息…

“揾”钱,最紧要系稳

我是腾讯安全的樊自磊。我们团队在腾讯主要负责金融风控产品&#xff0c;解决相关产品交付和服务维护工作&#xff0c;像国内知名大型国有银行、城商行、互联网金融公司等&#xff0c;都是我们的服务对象。今年春节&#xff0c;我和我的的同事们都在深圳为金融行业的网络安全进…

连续多输入多输出对象最优控制

连续多输入多输出对象最优控制 控制对象:平面二自由度机械臂 动力学模型: M ( q ) q + C ( q , q ) + G ( q ) =

【HDRP】自动生成的光照探针——Probe Volume

HDRP中&#xff0c;增加了Probe Volume&#xff0c;可代替旧版的光照探针Light Probe Group。 使用此功能的物体&#xff0c;不再需要光照贴图。 一、优缺点比较 详细说明可查看官方说明。 1.Probe Volume按像素而不是按对象发光&#xff0c;这意味着 HDRP 可以更准确地照亮…

软件著作权申请材料

(一)按要求填写的软件申请表; (二)软件的鉴别材料; 1、软件的操作手册&#xff1a;图文并茂的详细介绍软件的各功能&#xff0c;文档应不超过60页&#xff0c;超过60页应当删除中间内容&#xff0c;保留前后30页&#xff1b; 2、软件的源代码&#xff1a;每页不少于50行&…

Go第 15 章 :单元测试

Go第 15 章 &#xff1a;单元测试 15.1 先看一个需求 在我们工作中&#xff0c;我们会遇到这样的情况&#xff0c;就是去确认一个函数&#xff0c;或者一个模块的结果是否正确&#xff0c; 如&#xff1a; 15.2 传统的方法 15.2.1 传统的方式来进行测试 在 main 函数中&a…

k8s集群调度、亲和性、污点和容忍、pod状态、排障步骤

目录 一、调度约束 二、创建资源工作流程 三、Scheduler调度过程 1.Scheduler调度中考虑的问题 2.调度过程的步骤 3.预算策略&#xff08;predicate&#xff09;的常见算法 4.优选策略&#xff08;priorities&#xff09;的优先级 四、Pod 调度到指定Node节点 1.nodeNa…

微服务的服务拆分与远程调用

​ 哈喽大家好呀&#xff01;好久不见甚是想念&#xff0c;给大家拜个年啦~应该不晚吧(ಥ_ಥ) 放假在家确实是容易躺平&#xff0c;有心而无力呀哈哈哈哈。但是闲着也是闲着&#xff0c;最近学了学微服务相关知识&#xff0c;马上也快毕业了就更到抓紧了 今天我来说说关于微服…

医疗影像容积重建-物体坐标系和渲染图像坐标系

1 物体坐标系&#xff08;mm为单位&#xff0c;并三方向都是各向同性的情况)将所有数据的正中间&#xff08;这里所有的数据&#xff0c;是指各体素按照实际位置在空间排列&#xff09;&#xff0c;作为物体坐标系的原点&#xff0c;以图像的image orientation X方向&#xff0…

Android开机动画

1.动画的位置 android开机动画位置在/system/media目录下&#xff0c;/system/media/bootanimation.zip 解压是如下的文件内容 part0&#xff0c;part1&#xff0c;part2存放的都是要播放开机动画的帧图片&#xff0c;desc.txt写的是播放方式&#xff0c;desc文件内容类似如下…

天云数据Hubble数据库荣获2022年度IT168技术卓越奖

在2022年即将结束之际&#xff0c;IT168再次启动“技术卓越奖”评选。由行业CIO/CTO大咖、技术专家及IT媒体三方联合评选&#xff0c;评判标准代表了用户和媒体声音。经过多方评审&#xff0c;天云数据Hubble数据库荣获2022年度IT168技术卓越奖。 IT168主编任朝阳说&#xff1a…

SAP FICO 内部订单详细解析

内部订单 内部订单是用来对企业内部某项工作或者任务编制计划、归集成本、结算的载体。比如市场推广活动、内部团队活动、研发项目、投资项目、在建工程项目等。 内部订单需要区别于销售订单、采购订单和生产订单。 销售订单和采购订单是企业与外部单位以合同或者契约为纽带&…

Socket缓冲区,可读可写条件

一 socket缓冲区 每个 socket 被创建后&#xff0c;都会分配两个缓冲区&#xff0c;输入缓冲区和输出缓冲区。 write()/send() 并不立即向网络中传输数据&#xff0c;而是先将数据写入缓冲区中&#xff0c;再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区&…

从0到0.1学习 maven(一:概述及简单入门)

文章目录概述从没用的有趣小知识开始Maven是什么&#xff1f;为什么用Maven&#xff1f;使用与配置入门目录结构编写pom使用Archetype生成骨架小彩蛋&#xff1a;直接运行包含main的jar概述 从没用的有趣小知识开始 Maven可以翻译成“知识的累积”&#xff0c;“专家/行家”。…

数据质量管理深入浅出

质量是生活中最常关注的话题&#xff0c;我们都期望享用高质量的商品与服务&#xff0c;且企业也不断加大质量管理的投入&#xff0c;为了更好的用户体验。 在企业数字化转型浪潮下&#xff0c;传统手段已无法应对数字化转型中的数据质量管理需求&#xff0c;我们需要探索出一条…

千万级数据,如何做性能优化?分库分表、Oracle分区表?

目录一、Oracle是如何存储数据的&#xff1f;1、逻辑存储与物理存储2、进一步分析它们之间的关系3、Oracle逻辑数据块&#xff08;1&#xff09;块头&#xff08;2&#xff09;行数据&#xff08;3&#xff09;可用空间&#xff08;4&#xff09;致块头增长的原因有&#xff1a…

关于我给dumi2.0提pr的完整记

前言 博主最近一年时间在工作业余都在写开源组件库 concis &#xff0c;其中文档站点生成框架采取了 dumi&#xff0c;前几天不久dumi2.0正式发布&#xff0c;博主也是顺势而为直接把项目升级&#xff08;dumi1 -> dumi2&#xff09; 由于dumi2 的站点设计比原来好看太多了…