react setState 中使用函数替代对象

news2024/11/17 11:29:48

遇到的问题:
调用很多次 setState, 最后的值并不是我想要的值 -偶现问题(60%)

修改前代码

  const [data, setData] = useState<T>((options?.initialValues || {}) as T);
  const resetForm = (values: Partial<T>) => {
    // 常用写法 -此刻data,有可能不是最新的值
    setData({ ...data, ...values } as T);
  };

修改后代码

  const [data, setData] = useState<T>((options?.initialValues || {}) as T);
  const resetForm = (values: Partial<T>) => {
    // 函数写法[强烈推荐] -preData永远是前一个值
    setData((preData) => {
      console.log("predata", preData);
      console.log("data", data);
      return {
        ...preData,
        ...values,
      };
    });
  };

这里所打印的东西如下图所述 console.log("predata", preData); console.log("data", data);

在这里插入图片描述
可以看出这里的 data 不是最新的,而是一直变化的!


常用写法

import React, { useState, useEffect } from "react";

const CodeMirrorDemo = () => {
  const [value, setValue] = useState(0);

  useEffect(() => {
    for (let i = 0; i < 3; i++) {
      // setValue((prevData) => prevData + 1);
      setValue(value + 1);
    }
  }, []);

  return <>TEST {value}</>;
};

export default CodeMirrorDemo;

结果图:
在这里插入图片描述

通过for循环,执行了3次setValue(value+1),那么你觉得value会 +3 吗?
答案是:肯定不会

无论for循环执行几次,最终实际结果都将是仅仅执行一次 +1。

为什么?
类组件中setState赋值过程是异步的,同样在Hook中 setXxx 赋值也是异步的,比如上述代码中的setValue。

虽然执行了3次setValue(value+1),可是每一次修改后的value并不是立即生效的。当第2次和第3次执行时获取到value的值和第1次获取到的value值是一样的,所以最终其实相当于仅执行了1次。

补充:
直接在 setValue 中依赖 value 计算新的value 在异步执行的函数中会由于 js 闭包捕获得到预期外的结果,
此时可以使用 setValue((prevData) => prevData + 1); 函数式更新来解决。

函数写法

import React, { useState, useEffect } from "react";

const CodeMirrorDemo = () => {
  const [value, setValue] = useState(0);

  useEffect(() => {
    for (let i = 0; i < 3; i++) {
       setValue((prevData) => prevData + 1);
      // setValue(value + 1);
    }
  }, []);

  return <>TEST {value}</>;
};

export default CodeMirrorDemo;

结果图:
在这里插入图片描述

相关连接:
-https://juejin.cn/post/6844903459842424839
-https://medium.com/@wisecobbler/using-a-function-in-setstate-instead-of-an-object-1f5cfd6e55d1#.hwznlbxsa
-添加链接描述

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

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

相关文章

外链建设技巧,助你成为搜索引擎中的佼佼者!

终于&#xff0c;SEO 系列来到了正篇的终章&#xff0c;恭喜你&#xff0c;你很快就可以向更加专业的 SEO 专家再迈进一步了&#xff01; 今天&#xff0c;我们将和你一起&#xff0c;带上之前所学的知识、技巧&#xff0c;从实战出发&#xff0c;像手术台上的主刀医生那样&am…

16:00面试,16:08就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推我…

通过systemctl管理服务

文章目录 通过systemctl管理服务通过systemctl管理单一服务(service unit)使用案例服务启动/关闭/查看的练习关于systemctl命令启动/停止服务后面的后缀名是否加&#xff1f; 通过systemctl查看系统上所有的服务使用案例 通过systemctl管理不同的操作环境(target unit)使用案例…

面试京东失败,再看看2年前的面试题,根本不是一个难度···

刚从京东走出来&#xff0c;被二面难到了&#xff0c;我记得学长两年前去面试的时候&#xff0c;问的问题都特别简单&#xff0c;咋现在难度高了这么多。面试前我也刷过很多的题和看过很多资料&#xff0c;后来想想&#xff0c;这年头网上资料泛滥&#xff0c;测试面试文档更是…

JVM 方法区

栈、堆、方法区的交互关系 线程共享角度: 新建对象分配: 方法区的理解 方法区(Method Area) 与 Java 堆一样&#xff0c;是各个线程共享的内存区域方法区在 JVM 启动的时候被创建&#xff0c;并且它的实际物理内存空间中和 Java 堆区一样都可以不连续的方法区的大小&#xf…

08-02 底层数据设计策略 - 分库分表,热点热数据隔离

关系型数据库的伸缩 读写分离 缓存和搜索引擎本质上也是一种读写分离 商品是典型的读多写少的场景 分库分表 略知一二 分表 分库 业务量大的数据基本都得使用分库分表&#xff0c;不然单表的数据量大之后&#xff0c;性能太差 数据迁移和扩容 成倍扩容 直接…

centos搭建redis并配置redis主从复制

一、gcc环境搭建 1.检查是否有gcc环境&#xff1a; gcc -v#运行命令 gcc -v #如果显示:-bash: gcc: command not found # 表示没有该环境 #如果显示下文&#xff0c;代表有gcc环境 Using built-in specs. COLLECT_GCCgcc COLLECT_LTO_WRAPPER/usr/libexec/gcc/x86_64-redha…

Java中ArrayList的三种构造方法

ArrayList的构造方法 //三种构造方法 ArrayList()// 无参构造 ArrayList(Collection<? extends E> c) //利用其他 Collection 构建 ArrayList ArrayList(int initialCapacity) //指定顺序表初始容量1.无参构造方法 其中elementData是一个成员数组&#xff0c;类型是Ob…

什么是敏捷开发?敏捷开发流程的8个步骤

文章目录 一、什么是敏捷开发&#xff1f;二、敏捷开发模式的分类三、SCRUM 的工作流程四、敏捷开发流程的8个步骤包括&#xff1a;五、敏捷开发模型 一、什么是敏捷开发&#xff1f; 敏捷开发&#xff08;Agile&#xff09;是一种以人为核心、迭代、循序渐进的开发方法。 在…

phpstorm 配置xdebug

目录 配置全局环境 phpstorm 项目xdebug配置 额外补充&#xff1a; 配置全局环境 本地运行命令 php -v, 看是否有Xdebug相关的信息若没有&#xff0c;安装xdebug&#xff0c;以下是mac相关方式&#xff1a; pecl search xdebug 查询&#xff0c;找到之后用 pecl install xdebug…

【企业信息化】第4集 免费开源ERP: Odoo 16 Rental租赁管理系统

文章目录 前言一、概览二、使用功能1.提高出租效率2.产品 & 价格3.销售订单4.跟进5.报告6.集成 三、总结 前言 唯一可以满足您所有需求的租赁软件 从时间安排到开具发票。 您的所有租赁流程都集中在一处。 一、概览 从租金报价到发票 从一处管理所有事务。 从一个视图创建您…

强力推荐,两款Excel插件,极致好用,让你秒变高手

Excel是我们日常生活工作中应用最多、业界最标准的表格软件。 由于Excel的用户数量非常庞大&#xff0c;在社区支持方面非常丰富&#xff0c;用户可以轻松地找到各种教程和解决方案。 虽然Excel很功能已经成熟&#xff0c;但自身也存在一定的局限性&#xff0c;很多用户在网上…

git仓库新建项目第一次推送代码流程记录

git仓库新建项目第一次推送代码流程记录 换了个坑之后,公司改用SVN管理代码,隔了好长时间没用git,突然又捡起来,有点懵逼,简单记录一下。 电脑安装git之后,在项目父文件夹处,右键选择“Git Bash Here”打开git小黑窗。 在gti后台创建新项目目录之后,如果是空的项目,…

洛谷P1909-买铅笔

洛谷P1909-买铅笔 大家来看一道简单的题&#xff0c;第一次写的时候我过了一半&#xff0c;看了半天自己的代码&#xff0c;还感觉没问题&#xff0c;还是学艺不精啊 先看题目 #include <iostream> using namespace std; int n;//要买的铅笔数 int n1,m1; int n2,m2; i…

(数字图像处理MATLAB+Python)第八章图像复原-第一节:图像复原概述

文章目录 一&#xff1a;图像复原概述二&#xff1a;图像退化模型&#xff08;1&#xff09;连续退化模型&#xff08;2&#xff09;离散退化模型 三&#xff1a;图像退化函数的估计&#xff08;1&#xff09;基于模型的估计法&#xff08;2&#xff09;运动模糊退化估计 一&am…

(双指针)leetcode11. 盛最多水的容器

文章目录 一、题目1、题目描述2、基础框架3、原题链接 二、解题报告1、思路分析2、时间复杂度3、代码详解 三、本题小知识 一、题目 1、题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中…

win10系统ssh连接阿里云linux服务器并传输文件教程

前言 因为业务需要&#xff0c;最近搞了一台linux的阿里云服务器&#xff0c;现在要连接阿里云服务器。 之前没有玩过这种云服务器&#xff0c;两眼一抹黑&#xff0c;在网上搜索资料也比较少&#xff0c;所以写篇博客记录一下连接的步骤&#xff0c;以防止忘记。 SSH命令行…

如何使用Nodejs搭建HTTP服务,实现公网远程访问「内网穿透」

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 转载自内网穿透工具的文章&#xff1a;使用Nodejs搭建HTTP服务&#xff0c;并实现公网远程访问「内网穿透」 前言 Node.js…

Linux 之 yum使用(yum 命令使用讲解)

一、yum介绍 Yum(全称为 Yellow dogUpdater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动下载RPM包并且安装&#xff0c;可以自动处理依赖性关系&#xff0c;并且一次安装所有依赖的软件包&#x…

优思学院|何时应该使用8D方法?

8D&#xff08;Eight Disciplines&#xff09;过程是一种用于问题解决和改进的方法&#xff0c;其包含8个步骤。 D0是准备8D过程的阶段&#xff0c;其作用在于帮助我们判断是否需要使用8D来解决问题。如果问题的根本原因明显&#xff0c;可以通过直接采取措施来解决异常&#…