React input输入相关:受控方式无法更新对象类型数据(函数式组件 useState)

news/2024/11/17 1:55:04/

假设,要做一个登录系统,需要输入账号和密码,账号和密码由一个对象userInfo进行管理,我们可以初始化一个对象

let [userInfo, setUserInfo] = useState({account: "",password: ""
})

输入框可以采用受控方式:

<div className="inputItem"><span>账号: </span><Inputplaceholder="请输入邮箱"value={userInfo.account}onChange={(e) => handleInput(e, "account")}type="text"></Input>
</div>
<div className="inputItem"><span>密码: </span><Inputplaceholder="请牢记您的密码"value={userInfo.password}onChange={(e) => handleInput(e, "password")}type="password"></Input>
</div>

如果你的onChange的处理函数是这样写的:

const handleInput = (e, type) => {if (type === "account") {setUserInfo(pre => {pre.account = e.target.valuereturn pre})} else {setUserInfo(pre => {pre.password= e.target.valuereturn pre})}
};

你会发现一个问题:虽然pre确实是被修改了,也确实是被返回了,但是不管输入什么input都是没有值的(userInfo实际上没有被修改)。

这个问题的关键其实我们都知道:state不能通过直接赋值的方式修改,这也是我们为什么要解构出setUserInfo的原因

到这里你可能很疑惑,我是用的setUserInfo呀?

但是看上面传入setUserInfo中的函数,传入函数是为了解决需要用到之前的state值的需求,这个pre就是之前的 state,可是在这个函数中,却直接使用了pre.account = e.target.value这样的形式,用 = 给一个 state 赋值了!

既要获取之前的state值,又不能在原先的state对象上面直接修改,所以我们使用深拷贝这个方法,生成一个临时对象,在这个上面修改,然后通过setUserInfo更改state:

 const handleInput = (e, type) => {let temp = JSON.parse(JSON.stringify(userInfo)); // 深拷贝对象if (type === "account") {temp.account = e.target.value;} else {temp.password = e.target.value;}setUserInfo(temp);};

http://www.ppmy.cn/news/7689.html

相关文章

这篇文章详细介绍动态内存管理 ,让你醍醐灌顶【c语言】

文章目录动态内存函数mallocfreecallocrealloc常见的动态内存错误对NULL指针的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放一块动态开辟内存的一部分对同一块动态内存多次释放动态开辟内存忘记释放&#xff08;内存泄漏&#xff09;练习柔性数…

死锁的成因以及解决方案

&#x1f388;专栏链接:多线程相关知识详解 目录 一.什么是死锁以及死锁的成因 Ⅰ.一个线程一把锁 Ⅱ.两个线程两把锁 Ⅲ.多个线程多把锁 二.死锁的解决方案 一.什么是死锁以及死锁的成因 死锁是一个线程加上锁了之后,解不开了 在多线程编程中&#xff0c;我们为了防止多…

剑指offer----C语言版----第二天

目录 1. 二维数组中的查找 1.1 题目描述 1.1 思路一 1.2 思路二 1.3 思路三&#xff08;最优解&#xff09; 1. 二维数组中的查找 原题链接&#xff1a;剑指 Offer 04. 二维数组中的查找 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/er-wei-shu-…

QT学习 控件(二)输入文本类

文章目录QLineEditQTextEditQTextCursorQLineEdit QLineEdit是最基本的输入控件&#xff0c;继承自QObject &#xff0c;常用于短行的输入。 构造函数&#xff1a; 可以指定一个默认文本以及父窗口 QLineEdit(const QString &contents, QWidget *parent nullptr)QLineE…

前端面试题之计算机网络篇--HTTP协议

HTTP协议 1. GET和POST的请求的区别 GET和POST方法 GET和POST方法都是HTTP中的方法 什么是 HTTP&#xff1f; 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;缩写 HTTP&#xff09;旨在启用客户端和服务器之间的通信。 HTTP 充当客户端和服务器之间的…

花费数小时,带你学透Java数组,这些常用方法你还记得吗?

推荐学习专栏&#xff1a;Java 编程进阶之路【从入门到精通】 文章目录1. 数组2. 一维数组2.1 声明2.2 初始化2.3 使用3. 二维数组3.1 声明3.2 初始化3.3 使用4. 数组在内存中的分布5. 数组常用的方法5.1 Arrays.toString方法5.2 Arrays.copyOf方法5.3 Arrays.copyOfRange方法5…

Qt编写雷达模拟仿真工具1-背景布局

一、前言 雷达模拟仿真工具&#xff0c;整体结构采用的QGraphicsView框架&#xff0c;背景布局采用的分层绘制&#xff0c;这样可以控制该需要重新绘制的重新绘制&#xff0c;不需要重新的绘制的就没必要再多余的浪费&#xff0c;这里定义了一个GraphicsBackGroundItem类继承自…

freeswitch的gateway实现出中继的主备方案

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 某些呼叫场景中&#xff0c;我们有2条出中继线路可选&#xff0c;2条出中继需要按照主备模式来配置&#xff0c;优先使用主中继呼叫&#xff0c;当主中继出现问题时&#xff0c;呼叫自动转移到备用中继呼叫。 本节中&a…