1.react useState使用与常见问题

2023-11-04

用于为函数组件引入状态

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style></style>
  <script src="../react.development.js"></script>
  <script src="../react-dom.development.js"></script>
  <script src="../babel.min.js"></script>
  <script src="../lodash.min.js"></script>
</head>

<body>
  <div id="app"></div>
  <script type="text/babel">
   
    let app = document.querySelector('#app');
    let root = ReactDOM.createRoot(app);
    let { flushSync } = ReactDOM;

    let { useState, useEffect } = React;

    let Welcome = (props)=>{
        const initCount = () => {
        console.log('initCount');
        return 2*2*2;
      }
      // 5. 初始需要大量计算的情况,可以写一个回调函数,这样可以惰性加载函数,只让函数调用一次
      const [count, setCount] = useState(()=>{
        return initCount();
      });
      const [msg, setMsg] = useState('hello');
      
      // 4.利用扩展运算符的形式来解决对象修改的问题
      // const [info, setInfo] = useState({
      //   username: 'xiaoming',
      //   age: 20
      // })
      // setInfo({
      //   ...info,
      //   username: 'xiaoqiang'
      // })

      const handleClick = () => {
         //0. 取消批处理合并更新, render 2次
        // flushSync(()=>{
        //   setCount(count + 1)
        // })
        // flushSync(()=>{
        //   setMsg('hi')
        // })

        // 1. 合并更新,setCount(异步更新) 3次相当于1次, count值为1
        // setCount(count + 1)
        // setCount(count + 1)
        // setCount(count + 1)

        // 2. 如何取消批处理合并,让值累加?,改为回调函数写法,内部会依次执行函数, 执行3次  count值为3
        // setCount((count)=> count+1)
        // setCount((count)=> count+1)
        // setCount((count)=> count+1)

        // 3. 异步更新,获取异步更新的值?
        // 在setCount执行后,直接获取值,发现是更新前的值.如何修复?

        // 在类组件中,是通过setState,的第二个参数,在回调函数中获取同步数据

        // 函数组件中useState,没有第二个参数获取这个同步更新的值,   需要使用useEffect,监听,获取同步更新的值


        // 既然要进行自动批处理操作,所以函数是异步的
        // useState():对应响应式数据的修改函数是没有第二个参数的,所以要监听数据改变后的时机,在函数组件中是通过 useEffect() 来实现的
        // setCount(count + 1, ()=>{   // ✖
        //   console.log(count)
        // })



      }
      console.log(123);
      return (
        <div>
          <button onClick={handleClick}>点击</button>
          <div>hello world, { count }, { msg }</div>
        </div>
      );
    }
   



   
    

    let element = (
      <Welcome />
    );

    root.render(element)

  </script>
</body>

</html>

0. 取消批处理合并更新, render 2次

    // flushSync(()=>{
    //   setCount(count + 1)
    // })
    // flushSync(()=>{
    //   setMsg('hi')
    // })

1. 合并更新,setCount(异步更新) 3次相当于1次, count值为1

    // setCount(count + 1)
    // setCount(count + 1)
    // setCount(count + 1)

2. 如何取消批处理合并,让值累加?,改为回调函数写法,内部会依次执行函数, 执行3次 count值为3

    // setCount((count)=> count+1)
    // setCount((count)=> count+1)
    // setCount((count)=> count+1)

3. 异步更新,获取异步更新的值?useEffect

用useEffect监听同步
// 在setCount执行后,直接获取值,发现是更新前的值.如何修复?

    // 在类组件中,是通过setState,的第二个参数,在回调函数中获取同步数据

    // 函数组件中useState,没有第二个参数获取这个同步更新的值,   需要使用useEffect,监听,获取同步更新的值


    // 既然要进行自动批处理操作,所以函数是异步的
    // useState():对应响应式数据的修改函数是没有第二个参数的,所以要监听数据改变后的时机,在函数组件中是通过 useEffect() 来实现的
    // setCount(count + 1, ()=>{   // ✖
    //   console.log(count)
    // })

4. 结合useRef处理

问题:React开发中经常会遇到,组件渲染时都是上一次的数据,每次修改state数据,都不会立即在页面上显示更新。

原因:这是由于React里事件分为合成事件和原生事件,合成事件和钩子函数都是异步的,原生事件是同步的。由于useState是异步事件,所以会出现异步更新问题。在调用setData()的过程中,不要试图立即获取数据状态的变化。

解决方案:使用useRef存储数据,useEffect监听数据变化,并进行更新。

定义:

const [initEditClassFormData, setInitEditClassFormData] = useState();
 
const initFormRef = useRef();
 
useEffect(() => {
    initFormRef.current = initEditClassFormData;
  }, [initEditClassFormData]);

调用:使用时,不再用initEditClassFormData,使用initFormRef.current

initFormRef.current

5.利用扩展运算符的形式来解决对象修改的问题

  // const [info, setInfo] = useState({
  //   username: 'xiaoming',
  //   age: 20
  // })
  // setInfo({
  //   ...info,
  //   username: 'xiaoqiang'
  // })

6. 初始值大量计算,优化

初始需要大量计算的情况,可以写一个回调函数,这样可以惰性加载函数,只让函数调用一次

  const [count, setCount] = useState(()=>{
    return initCount();
  });
  const [msg, setMsg] = useState('hello');

FAQ

https://zh-hans.legacy.reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies

小结

讨论了下useState会遇到的一些问题,与优化技巧

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1.react useState使用与常见问题 的相关文章

  • ReactiveX:仅对每组中的最后一项进行分组和缓冲

    如何对 Observable 进行分组 并从每个 GroupedObservable 中仅将最后发出的项保留在内存中 这样每个组的行为就像BehaviorSubject 一样 像这样的东西 user 1 msg Anyone here us
  • 在其他不可滚动的 div 上滚动时如何滚动可滚动的 div?

    我知道这个问题听起来很令人困惑 但这就是我想要做的 在下面的代码片段中 如果用户在绿色 div 上滚动 我希望黄色 div 相应地滚动 就像滚动黄色 div 一样 请注意 黄色 div 有overflow auto 但绿色的则不然 docu
  • 如何将 Django 中的数组传递给模板并在 JavaScript 中使用它

    我想将数组传递给模板 然后通过 JavaScript 使用它 In my views py I have arry1 Str 500 20 return render to response test html array1 arry1 在
  • 为什么隐式符号到字符串转换会导致 JavaScript 中出现类型错误?

    有一个 toString on Symbol在 ES6 中 它返回字符串表示形式Symbol 但想知道为什么 Symbol 不起作用 运行这个表达式会抛出TypeError我没想到 后者只是打电话吗 toString 在一个新的Symbol
  • 实现悬停信息框

    我有一个日历 当用户将鼠标悬停在单元格上时 会出现一个很大的信息框 其中包含该日期的详细信息 虽然当用户离开时使信息框消失 但我遇到了一些麻烦 我基本上想要它 这样当鼠标光标移出信息框隐藏的日历单元格时 它就会消失 但我遇到了麻烦 因为mo
  • 递归修剪对象中所有元素的更好方法?

    如果我有一个像这样的物体 const obj field subfield innerObj a asdasd asdas innerArr s ssad innerArrObj b adsad 我想出了这样的东西 const trimFi
  • React 应用程序中的 addEventListener 不起作用

    一些背景 我正在尝试消费自定义网络组件在 React 应用程序中并尝试监听来自 Web 组件的事件 我相信您不能只在自定义 Web 组件上以通常的反应方式处理事件 i e
  • React 在同一组件中渲染多个模态

    我对 React 和一般编码都很陌生 我试图在同一组件中渲染多个模态 但它们都是同时渲染的 因此看起来所有链接都在最后一个模态中渲染文本 这是状态设置的地方 class Header extends React Component cons
  • 为什么我们使用 SpreadsheetApp.flush()?

    我的理解是 flush https developers google com apps script reference spreadsheet spreadsheet app flush有助于在功能发生时执行这些功能 而无需将它们捆绑在
  • setInterval() 在用户离开选项卡时暂停?

    javascript 中是否有任何方法的行为类似于 setInterval 并且当用户离开选项卡时停止并在用户再次进入选项卡时恢复 您可以使用以下方法创建自己的 API可见性API https developer mozilla org e
  • 避免在 ES6 的函数内定位 this 的对象作用域

    例如 我正在使用 D3 js 运行一个项目 导入特定模块并调用它们的函数 Setup TypeScript ES6 导入特定的 D3 组件 角6 我有一个对象 在本例中是一个角度指令 并在 SVG 画布上绘制一些圆圈 并希望它们在拖动事件上
  • 窗口大小调整触发的 DOM 事件

    我有一个布局相当复杂的页面 最初打开页面时 某些元素的对齐存在问题 但是 可以通过更改浏览器窗口的大小来 永久 解决此问题 显然 我不希望用户必须调整浏览器窗口的大小才能使页面正确显示 所以我想知道是否有一种方法可以在页面首次加载时以编程方
  • 带有 mkdocs 的本地 mathjax

    我想在无法访问互联网的计算机上使用 MathJax 和 Mkdocs 因此我不能只调用 Mathjax CDN Config mkdocs yml site name My Docs extra javascript javascripts
  • 尝试使用 Firebug 查找 JavaScript 文件中的函数

    我试图找到这个函数调用 myFooBar 该函数在某些 HTML 中内联引用 但页面加载了大量 JavaScript 并且在每个文件中搜索该函数需要相当多的工作 如何使用 Firebug 找到此函数所在的 JavaScript 文件 打开脚
  • 如何使用 JavaScript 获取元素的填充值?

    我有一个textarea在我的 HTML 中 我需要获取整数或浮点形式的填充数值 以像素为单位 我如何使用 JavaScript 获取它 我没有使用 jQuery 所以我正在寻找纯 JavaScript 解决方案 这将返回padding l
  • Outlook 加载项,无法读取未定义的属性“BeginRequestEventArgs”

    我使用 Visual Studio 开发了 Outlook 插件 我的插件有一个按钮 用于填充会议邀请正文中的详细信息并添加所需的与会者 这在 99 的情况下都有效 但是 时不时地它会给我下面的 JavaScript 错误 Uncaught
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • Javascript 中 if 语句中的假值?

    过去两周 我在学校研究 JavaScript 的事情已经有一段时间了 而且我一直在做我的作业 在 Douglas Crockford 所著的 JavaScript The Good Parts 一书中 作者在第 11 页上列出了 if 语句
  • 具有固定顶部菜单的语义 UI 侧边栏

    Semantic UI 对其进行预警侧边栏页面 http semantic ui com modules sidebar html usage 当侧边栏出现时 固定位置内容可能会出现改变其位置的问题 然后它提供了该问题的两种可能的解决方案
  • p5 向量减法“sub”返回错误

    我一直在尝试将 p5 草图上传到 React 构建中 使用react p5 wrapper 我能够成功在屏幕上渲染画布 但是 某些矢量函数会导致错误 var distance this position dist ball position

随机推荐

  • 在pycharm中配置变量

    实验目的 python run classifier py task name MRPC do train true do eval true data dir GLUE DIR MRPC vocab file BERT BASE DIR
  • es 索引类型与分词器调整与迁移

    索引最好起别名 方便索引调整 1 创建新索引 PUT index v2 settings number of shards 5 number of replicas 1 mappings doc dynamic strict propert
  • Python爬虫中文乱码问题

    我们在爬虫输出内容时 常常会遇到中文乱码情况 以如下网址为例 https chengdu chashebao com yanglao 19077 html 在输出内容时 出现如下图的情况 解决爬虫中文乱码的步骤 网址编码为gbk 查看网页源
  • shell与shell脚本(一)基本概念与常用的shell命令

    前言 像linux windows等的操作系统 都很大程度上地便利了我们操作计算机的能力 计算机之所以能高效处理用户指令 是因为CPU 更细致地讲 是因为CPU中的内核 也就是我们所说的运算器 控制器和寄存器 当然 我们在使用计算机是 不可
  • 四、同步方法与异步方法及回调函数

    解释一下同步方法与异步方法以及回调函数的关系 若不想很深入的了解这方面内容 可以记住以下结论 对于同时有同步方法和对应异步方法的函数 我们常用异步方法 用独立线程去处理该函数 提高用户的体验 异步方法由于我们需要等待某种事件的发生 例如当前
  • mysql插入数据时,在数据库和表的编码都是utf-8的情况下,还是出现乱码

    Mysql插入数据时 在数据库和表的编码都是utf 8的情况下还是会出现乱码 解决方法 首先先确定自己的数据库的编码是否是utf 8 查看数据库字符集 将sct换为自己的数据库的名字 SHOW CREATE DATABASE sct 会看到
  • vue 项目 基于axios 对常用5种(POST、GET、PUT、DELETE、PATCH)请求进行封装

    一 安装axios 使用 npm npm install axios save 使用 cnpm cnpm install axios save 使用 yarn yarn add axios save 建议使用cnpm 二 src目录下新建l
  • c语言 什么时候需要动态分配内存?

    我讲解一下c语言中动态分配内存的函数 可能有些初学c语言的人不免要问了 我们为什么要通过函数来实现动态分配内存呢 系统难道不是会自动分配内存吗 既然有人会问这样的问题 那么我在这里好好的讲解一下吧 首先让我们熟悉一下计算机的内存吧 在计算机
  • qt中的线程

    目前我暂时会两种线程方式 一种是继承QTHRead 另一种是movetothread 相对二样 第二种好一些 先来介绍一下第一个方法 继承QTHread public A QThread void run 重新run函数 public B
  • python sqlalchemy 多对多

    调用Column创建字段 加类型 from sqlalchemy import Table Column Integer String DATE ForeignKey 调用操作链接 反查 from sqlalchemy orm import
  • 数据结构--树与二叉树

    一 树的概述1 树的基本概念 N个结点组成一对多关系的层次结构 N 0 为空树 N 1 只有根结点的树 N gt 1 树 A 逻辑定义 前驱后继 有且仅有一个根结点 除根结点外 每一个节点有且仅有一个前驱结点 每个结点可以有0个或多个后继结
  • 冒险岛 vcruntime140.dll 丢失问题的多种方法,几种解决方法都有效

    当您尝试启动冒险岛游戏时 可能会遇到一个名为 vcruntime140 dll 丢失 的错误提示 vcruntime140 dll 是冒险岛游戏所需的一个重要系统文件 如果系统无法找到或加载该文件 您将无法正常启动游戏 在本文中 我们将详细
  • 测试存储过程中中发生异常时,之前DML操作会不会rollback

    span style font family none span style font size 14px 步骤 span span span style font size 14px 1 向表中productinfo插入一条数据 span
  • vosviewer保存成PDF文件时没有文字

    1 将vosviewer中英文国家名字 手工更换为中文后 重新导入软件 2 点击Screenshot后面的三角标 并选择 Save 3 打开PDF文件 发现另存的PDF中没有文字 还在研究如何解决
  • UI/UX记——Adobe XD

    文章目录 前言 一 Adobe XD是什么 二 3D 变换 开启全新维度进行设计 实现不可能 在作品中实现三维效果 助力流程与时俱进 操作 1 选择组件 2 启用 3D 变换 3 旋转和移动 组件 使用可重复使用的设计元素进行扩展 深入令人
  • Java:详解List集合的排序功能

    概述 List集合有两大排序方式 分别为自然排序和自定义排序 使用自然排序 需要元素类达到某种要求 使用自定义排序 就是在需要排序的时候才传入排序规则 自然排序 自然排序是 Collections sort 方法 只带一个参数 参数为Lis
  • (Java)蓝桥杯_分巧克力

    题目描述 儿童节那天有K位小朋友到小明家做客 小明拿出了珍藏的巧克力招待小朋友们 小明一共有N块巧克力 其中第i块是Hi x Wi的方格组成的长方形 为了公平起见 小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们 切出的巧克力需要满足
  • 判断对象为空

    一 判断对象为空的方法 1 使用Object keys 判断length是否为0 这里的0是Number类型 代码如下 2 使用JSON stringify 判断是否 代码如下 判断结果是否等于 去判断是否为空对象 3 使用for in 循
  • 使用Jquery设计列表

    1 截取文字内容实现控制列表宽度 使用的技术 1 jQuery的ready 函数 文档加载完成 2 jQuery的each 函数 遍历jQuery对象 3 jQuery的text 函数 所有匹配元素的内容 document ready fu
  • 1.react useState使用与常见问题

    文章目录 0 取消批处理合并更新 render 2次 1 合并更新 setCount 异步更新 3次相当于1次 count值为1 2 如何取消批处理合并 让值累加 改为回调函数写法 内部会依次执行函数 执行3次 count值为3 3 异步更