当前位置: 首页 > article >正文

React---day8

9.6 不可变数据的力量

我们知道是不能够修改this.state里面的数据的

举个例子

export class App extends React.PureComponent{constructor(){super();this.state = {userList:[{name : "tom" , age : 18},{name : "lily" , age : 20},{name : "tiki" , age : 18},]}}render(){const userList =this.state.userListreturn (<div><ul>{userList.map((item , index , arr) => {return (<li key={index}>{item.name} + {item.age}</li>)})}</ul><button onClick={() => this.addNewUser()}>点击添加</button></div>)}

不推荐的做法:

        const newData = {name : "hcy" , age : 19}this.state.userList.push(newData);this.setState({userList:this.state.userList})

因为我们修改了state里面的数据,但是这种方式直接修改原数组,不符合 React 的不可变性原则

我们的APP继承了PureComponent,它有shouldcomponnets方法,这个方法必须发生改变才会执行,但是我们这样的方法指向同一个地址(相同)所以是不会改变的

**推荐做法:**不要直接修改 state,应该用新数组。

    const newData = {name : "hcy" , age : 19}this.setState({userList:[...this.state.userList , newData]//不要直接修改 state,应该用新数组。})

9.7 全局事件传递events

开发中跨组件之间的事件传递,使用events

通过npm或者yarn来安装events

 npm add events

events常用的API:

  • 创建EventEmitter对象:eventBus对象;
  • 发出事件:eventBus.emit(“事件名称”, 参数列表);
  • 监听事件:eventBus.addListener(“事件名称”, 监听函数);
  • 移除事件:eventBus.removeListener(“事件名称”, 监听函数);

事件演练:

import React, { PureComponent } from 'react'
import {EventEmitter} from 'events'
// 需求:点击profile中的按钮->进行跨组件之间的事件传递
// 1、创建EventEmitter对象:eventBus对象
const evebtBus = new EventEmitter();export default class App extends PureComponent {render() {return (<div><Header /><Profile/></div>)}
}
class Header extends PureComponent{// 进行监听componentDidMount(){// 添加事件监听// 3、监听事件:eventBus.addListener("事件名称", 监听函数);// (eventName: string | symbol, listener: (...args: any[]) => void):// this.handleSayHelloListener:没有括号,因为是函数evebtBus.addListener("sayHello" , this.handleSayHelloListener)}componentWillUnmount(){// 取消事件监听//  (...args: any[]) => void)// 4、 移除事件:eventBus.removeListener("事件名称", 监听函数);evebtBus.removeListener("sayHello" ,this.handleSayHelloListener)}// ...args// 多个参数要写多个形参handleSayHelloListener(str , num){console.log(str + num);}render (){return (<div>Hello World</div>)}
}
class Profile extends PureComponent{render (){return(<div>Hello Profile<button onClick={() => this.emmitEvent()}>点击Profile</button></div>)}
// 2、发出事件:eventBus.emit("事件名称", 参数列表);emmitEvent(){evebtBus.emit("sayHello" , "Hello Home" , 123)}
}

10、受控和非受控组件

10.1 refs的使用

  • 方式一:传入一个对象
    • 对象是通过 React.createRef() 方式创建出来的;
    • 使用时获取到创建的对象其中有一个current属性就是对应的元素;
  • 方式二:传入一个函数
    • 该函数会在DOM被挂载时进行回调,这个函数会传入一个 元素对象,我们可以自己保存;
    • 使用时,直接拿到之前保存的元素对象即可;
import React, { PureComponent } from 'react';
import Pure from './Pure';
export default class App extends PureComponent {constructor() {super();this.titleRef = React.createRef();this.titleEle = null;}render() {return (<div>{/* 1、React.createRef() */}<h2 ref={this.titleRef} >Hello World</h2>{/* 2、传入一个函数 */}<h2 ref={(args) => this.titleEle = args}>Hello World</h2><button onClick={() => this.changeRef()}>点击切换</button></div>);}changeRef() {this.titleRef.current.innerHTML = "Hello React";this.titleEle.innerHTML = "Hello React"}appAdd(){console.log(this.pureRef.current.btnAdd());}
}

10.2 ref的类型

ref 的值根据节点的类型而有所不同:

  • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性;
  • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性;
  • 你不能在函数组件上使用 ref 属性,因为他们没有实例;

举一个组件上使用ref的例子:

          // 组件的refthis.pureRef = React.createRef();{/* 3、当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性; */}<Pure  ref={this.pureRef}/><button onClick={() => this.appAdd()}>app+1</button>

10.3 受控组件

受控组件是单元素(如<input><textarea>等)的值由React的state进行“控制”,即组件的状态(state)是唯一数据源

import React, { PureComponent } from 'react'export default class App extends PureComponent {constructor(){super();this.state = {username:""}}render() {return (<div><form><input type='text'value={this.state.username}onChange={(e) => this.handleChange(e)}/><input type='submit'onClick={(e) => this.handleSubmit(e)}/></form></div>)}handleSubmit(event){event.preventDefault();console.log("提交内容:",this.state.username)}handleChange(event){this.setState({username:event.target.value})}
}

<input>value 属性绑定了 this.state.username,输入框的内容只能通过 setState 来改变。每当用户输入内容时,onChange 事件会触发 handleChange,进而更新 state,React 再把最新的 state 赋值给 input 的 value。

总结:
受控组件的输入值受 React 组件的 state 控制,React 负责管理和同步表单数据,这就是“受控”的含义。

其他受控通过组件:比如select

import React, { PureComponent } from 'react'export default class App extends PureComponent {constructor(){super();this.state = {fruit:"apple"//默认为苹果}}render() {return (<div><form onSubmit={(e) => this.handleSubmit(e)}>{/* 选择器 */}<select value={this.state.fruit}name='fruits'onChange={(e) => this.handleChange(e)}><option value="apple">苹果</option><option value="oringe">橘子</option><option value="bannana">香蕉</option></select></form></div>)}handleSubmit(event){event.preventDefault();console.log("提交内容:",this.state.fruit)}handleChange(event){this.setState({fruit:event.target.value})}
}

受控组件—多输入

要是不抽取代码就会很冗余

import React, { PureComponent } from 'react'export default class App extends PureComponent {constructor(){super();this.state = {username:"",password:""}}render() {return (<div><form><input type='text'name='username'value={this.state.username}onChange={(e) => this.handleChange(e)}/><input name='password'type='password'value={this.state.password}onChange={(e) => this.handleChange(e)}/><input type='submit'onClick={(e) => this.handleSubmit(e)}/></form></div>)}handleSubmit(event){event.preventDefault();const {username , password } = this.state;console.log("提交内容:",username , password )}
//   handleusernameChange(event){
//    this.setState({
//     username:event.target.value
//    })//   }
//    handlepasswordChange(event){
//    this.setState({
//     password:event.target.value
//    })//   }handleChange(event){this.setState({[event.target.name] : event.target.value})}
//   我们可以把handleChange写为一个,因为她们的样式是都是:
//     handle{key}Change(event){
//    this.setState({
//     {key}:event.target.value
//    })//   }
// 我们只需要动态更新key就好
// 1、input设置name
// 2、event.target.name得到不同的key
}

10.4 非受控组件的使用

如果要使用非受控组件中的数据,那么我们需要使用 ref 来从DOM节点中获取表单数据。

在非受控组件中通常使用defaultValue来设置默认值;

import React, { createRef, PureComponent } from 'react'export default class App extends PureComponent {constructor(){super();this.nameRef = createRef()//创建ref对象}render() {return (<div><form><input type='text'ref={this.nameRef}//绑定ref/><input type='submit'onClick={ this.handleSubmit}/></form></div>)}handleSubmit = (event) => {event.preventDefault();console.log("提交内容:",this.nameRef.current.value)}//箭头函数
}

相关文章:

React---day8

9.6 不可变数据的力量 我们知道是不能够修改this.state里面的数据的 举个例子 export class App extends React.PureComponent{constructor(){super();this.state {userList:[{name : "tom" , age : 18},{name : "lily" , age : 20},{name : "tik…...

C# Onnx 动漫人物人脸检测

目录 效果 模型信息 项目 代码 下载 参考 效果 模型信息 Model Properties ------------------------- stride&#xff1a;32 names&#xff1a;{0: face} --------------------------------------------------------------- Inputs ------------------------- name&am…...

C++内存列传之RAII宇宙:智能指针

文章目录 1.为什么需要智能指针&#xff1f;2.智能指针原理2.1 RAll2.2 像指针一样使用 3.C11的智能指针3.1 auto_ptr3.2 unique_ptr3.3 shared_ptr3.4 weak_ptr 4.删除器希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 智能指针是 C 中用于自动…...

PVE 虚拟机安装 Ubuntu Server V24 系统 —— 一步一步安装配置基于 Ubuntu Server 的 NodeJS 服务器详细实录1

前言 最近在基于 NodeJS V22 写一个全栈的项目&#xff0c;写好了&#xff0c;当然需要配置服务器部署啦。这个过程对于熟手来说&#xff0c;还是不复杂的&#xff0c;但是对于很多新手来说&#xff0c;可能稍微有点困难。所以&#xff0c;我把整个过程全部记录一下。 熟悉我…...

GitHub 趋势日报 (2025年06月03日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 2404 onlook 860 system-design-primer 380 nautilus_trader 372 agent-zero 357 …...

出现dev/nvmeOnip2 contains a file system with errors, check forced 解决方法

目录 前言1. 问题所示2. 原理分析3. 解决方法4. 彩蛋前言 爬虫神器,无代码爬取,就来:bright.cn Java基本知识: java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)【Java项目】实战CRUD的功能整理(持续更新)1. 问题所示 出现如下问题: dev/nvmeOnip2 co…...

Vue3.5 企业级管理系统实战(二十二):动态菜单

在前几篇内容中已完成菜单、角色及菜单权限等相关开发&#xff0c;若要在左侧菜单根据用户角色动态展示菜单&#xff0c;需对 Sidebar 中的相关数据进行修改。鉴于其他相关方法及类型已在前文实现&#xff0c;本文不再重复阐述。 1 修改 Sidebar 组件 在 src/layout/componen…...

磨皮功能 C++/C的OpenCV 实现

磨皮功能 C/C的OpenCV 实现 前提条件 OpenCV 安装&#xff1a; 你需要正确安装 OpenCV 库。C 编译器&#xff1a; 如 G。 C 代码 #include <opencv2/opencv.hpp> #include <iostream> #include <string>// 使用标准命名空间 using namespace std; using …...

蓝牙防丢器应用方案

蓝牙防丢器通常由两个主要部分构成&#xff1a;一个小型装置&#xff0c;亦称为标签&#xff0c;以及一个与之配对的手机应用程序。该标签内置一个微型蓝牙芯片&#xff0c;能够与配对的手机应用程序进行通信。一旦标签与手机之间的连接中断&#xff0c;手机应用程序便会接收到…...

TDengine 开发指南——高效写入

高效写入 本章内容将介绍如何发挥 TDengine 最大写入性能&#xff0c;通过原理解析到参数如何配置再到实际示例演示&#xff0c;完整描述如何达到高效写入。 为帮助用户轻松构建百万级吞吐量的数据写入管道&#xff0c;TDengine 连接器提供高效写入的特性。 启动高效写入特性…...

Linux kill 暂停命令

暂停进程 kill -19 在一台服务器上部署了360Pika服务&#xff0c;先用RedisClient连接一下&#xff0c;可以连接 现在暂停进程 暂停后发现再次连接无法连接 恢复进程 kill -18 恢复后可连接...

Unity与Excel表格交互热更方案

在Unity中实现与Excel表格的交互并支持热更是许多游戏开发中的常见需求。以下是几种实现方案&#xff1a; 1. 使用ScriptableObject存储表格数据 实现步骤&#xff1a; 将Excel表格导出为CSV格式 编写编辑器脚本将CSV数据导入到ScriptableObject 在运行时通过Resources或Ad…...

LVS、NGINX、HAPROXY的调度算法

目录 一、LVS&#xff08;Linux Virtual Server&#xff09;调度算法 &#xff08;一&#xff09;静态调度算法 &#xff08;二&#xff09;动态调度算法 二、NGINX调度算法 &#xff08;一&#xff09;内置调度算法 &#xff08;二&#xff09;第三方模块支持的调度算法…...

C++ 使用 ffmpeg 解码本地视频并获取每帧的YUV数据

一、简介 FFmpeg 是一个‌开源的多媒体处理框架‌&#xff0c;非常适用于处理音视频的录制、转换、流化和播放。 二、代码 示例代码读取一个本地视频文件&#xff0c;解码并将二进制文件保存下来。 注意&#xff1a; 代码中仅展示了 YUV420P 格式&#xff0c;其他 NV12/NV2…...

分布式微服务系统架构第143集:pom文件

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ https://1024bat.cn/ https://github.com/webVueBlog/fastapi_plus https://webvueblog.github.io/JavaPlusDoc/ ✅ 各字段说明及是否可改 字段名说明是否可修改修改建议…...

2.0 阅读方法论与知识总结

引言 本文将详细分析考研英语阅读做题步骤&#xff0c;并对方法论进行总结&#xff0c;最后通过真题练习巩固方法。 一、做题步骤 所有技巧都建立在精读真题的基础上&#xff01;建议按以下节奏复习&#xff1a; 1️⃣ 做题 先看题干了解文章大致主旨&#xff08;看看有没有…...

5. Qt中.pro文件(1)

本节主要讲.pro文件的作用和一些相关基础知识与操作。 本文部分ppt、视频截图原链接&#xff1a;[萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频] 1 PRO文件 1.1 pro文件作用 添加需要用到的QT模块&#xff0c;如通过QT module_name来添加需要用到的Qt模块。指定生…...

第八部分:第三节 - 事件处理:响应顾客的操作

用户与界面的互动是通过事件触发的&#xff0c;比如点击按钮、在输入框中输入文本、提交表单等。React 提供了一套跨浏览器的事件系统&#xff0c;让我们可以在组件中方便地处理这些事件。这就像点餐系统需要能够识别顾客的各种操作&#xff08;按键、滑动屏幕&#xff09;并作…...

共识机制全景图:PoW、PoS 与 DAG 的技术对比

目录 共识机制全景图&#xff1a;PoW、PoS 与 DAG 的技术对比 &#x1f9f1; 一、工作量证明&#xff08;PoW&#xff09; 原理概述 优点 缺点 示例代码&#xff08;Python&#xff09; &#x1f4b0; 二、权益证明&#xff08;PoS&#xff09; 原理概述 优点 缺点 …...

学习笔记085——Spring Data JPA笔记

1、什么是Spring Data JPA&#xff1f; Spring Data JPA 是 Spring 框架的一个子项目&#xff0c;它简化了基于 JPA (Java Persistence API) 的数据访问层的实现。它通过减少样板代码和提供默认实现&#xff0c;让开发者能够更快速地构建数据访问层。 1.1、主要特点 减少样板…...

可视化大屏工具对比:GoView、DataRoom、积木JimuBI、Metabase、DataEase、Apache Superset 与 Grafana

可视化大屏工具对比&#xff1a;GoView、DataRoom、积木JimuBI、Metabase、DataEase、Apache Superset 与 Grafana 在当今数据驱动的业务环境中&#xff0c;可视化大屏已成为企业展示数据洞察的重要工具。本文将从功能、部署、分享、参数化大屏四个维度对主流可视化大屏工具进…...

内网穿透:打破网络限制的利器!深入探索和简单实现方案

在如今这个数字化时代&#xff0c;网络已经成为我们生活和工作中不可或缺的一部分。但你是否遇到过这样的困扰&#xff1a;在家办公时&#xff0c;想要访问公司内部的文件服务器&#xff0c;却因为网络限制无法连接&#xff1b;搭建了一个炫酷的个人网站&#xff0c;却只能在自…...

如何选择合适的哈希算法以确保数据安全?

在当今数据爆炸的时代&#xff0c;从个人身份信息到企业核心商业数据&#xff0c;从金融交易记录到医疗健康档案&#xff0c;数据已然成为数字世界的核心资产。而哈希算法作为数据安全领域的基石&#xff0c;犹如为数据资产配备的坚固锁具&#xff0c;其重要性不言而喻。然而&a…...

简数采集技巧之快速获取特殊链接网址URL方法

简数采集器列表页提取器的默认配置规则&#xff1a;获取a标签的href属性值作为采集的链接网址&#xff0c;对于大部分网站都是适用的&#xff1b; 但有些网站不使用a标签作为链接跳转&#xff0c;而用javascript的onclick事件替代&#xff0c;那列表页提取器的默认规则将无法获…...

React 性能监控与错误上报

核心问题与技术挑战 现代 React 应用随着业务复杂度增加&#xff0c;性能问题和运行时错误日益成为影响用户体验的关键因素。没有可靠的监控与错误上报机制&#xff0c;我们将陷入被动修复而非主动预防的困境。 性能指标体系与错误分类 关键性能指标定义 // performance-me…...

AI 如何改变软件文档生产方式?

现代软件工程中的文档革命&#xff1a;从附属品到核心组件的范式升级 在数字化转型浪潮席卷全球的当下&#xff0c;软件系统的复杂度与规模呈现指数级增长。据Gartner最新研究显示&#xff0c;超过67%的企业软件项目延期或超预算的根本原因可追溯至文档系统的缺陷。这一现象在…...

激光干涉仪:解锁协作机器人DD马达的精度密码

在工业4.0的浪潮中&#xff0c;协作机器人正以惊人的灵活性重塑生产线——它们与工人并肩作业&#xff0c;精准搬运零件&#xff0c;完成精密装配。还能协同医生完成手术&#xff0c;甚至制作咖啡。 标准的协作机器人关节模组由角度编码器、直驱电机(DD马达)、驱动器、谐波减速…...

Windows如何定制键盘按键

Windows如何定制键盘按键 https://blog.csdn.net/qq_33204709/article/details/129010351...

go语言学习 第1章:走进Golang

第1章&#xff1a;走进Golang 一、Golang简介 Go语言&#xff08;又称Golang&#xff09;是由Google的Robert Griesemer、Rob Pike及Ken Thompson开发的一种开源编程语言。它诞生于2007年&#xff0c;2009年11月正式开源。Go语言的设计初衷是为了在不损失应用程序性能的情况下…...

使用Prometheus+Grafana+Alertmanager+Webhook-dingtalk搭建监控平台

一、监控平台介绍 1.监控平台简述普罗米修斯四件套,分别为Prometheus、Grafana、Alertmanager、Webhook-DingTalk。Prometheus一套开源的监控&报警&时间序列数据库的组合,由SoundCloud公司开发,广泛用于云原生环境和容器化应用的监控和性能分析。其提供了通用的数据…...