React Hook中useState更新延迟问题及解决

 更新时间:2022年08月05日 12:18:49   作者:CahierX  
这篇文章主要介绍了React Hook中useState更新延迟问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

React Hook中useState更新延迟

方法一:去掉useEffect的第二个参数

例如以下代码 错误实例

const[zoom, setZoom] = useState(0);
useEffect(() = >{
    document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
},[]);
function scrollFunc(e) {
    setZoom(zoom + 5)
}

会出现zoom永远等于 0+5, 而不是所谓的5, 10 ,15 为什么会这样呢? 因为useEffect执行时,会创建一个闭包,在每次监听到mousewheel运行时 闭包内部保存了zoom的初始化值 每次调用的时候都是取的初始化值0 所有会一直为0+5

怎么解决呢?

解决方案: 去掉useEffect中的空数组即可

const[zoom, setZoom] = useState(0);
useEffect(() = >{
    document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
    return () = >document.getElementById('workspace-content').removeEventListener("mousewheel", scrollFunc); // 记得解绑事件
});
function scrollFunc(e) {
    setZoom(zoom + 5)
}

方法二:将改变函数移入useEffect并将第二个参数设置为state

依旧用上面的例子

解决方法:正确示例

useEffect(() = >{
    document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
    return () = >document.getElementById('workspace-content').removeEventListener("mousewheel", scrollFunc);
    function scrollFunc(e) {
        setZoom(zoom + 5) e.preventDefault()
    }
},[zoom]);

方法三:使用Ref, 在useEffect内监听此ref, 并实时跟useState同步

例如下面的代码 错误示例

const [currentIndex, setCurrentIndex] = useState(0)
  const handleLeft = () => {
     setCurrentIndex(currentIndex+ 1)
     console.log(currentIndex)
  }

初始化currentIndex为0 每次执行handleLeft函 数是让currentIndex加1, 之后立即获取currentIndex的值发现 第一次执行currentIndex = 0

第二次执行currentIndex = 1 每次都跟实际情况差一个  查阅资料发现useState必须要执行完react整个生命周期才会获取最新值

解决方案:用useRef中转,并实时同步给useState 

const [currentIndex, setCurrentIndex] = useState(0)
const currentIndexRef = useRef(0);
  const handleLeft = () => {
     currentIndexRef.current += 1
     console.log(currentIndexRef.current)
  }
useEffect(()=>{
    setCurrentIndex(currentIndexRef.current)
},[currentIndexRef.current])

React Hook useState连续更新对象问题

react hook 的useState更新是异步的,所以在连续更新出发useState时会出现问题

eg: 

import React, {useState} from 'react';
 
export default () => {
    const [obj, setObj] = useState({
        a: 1,
        b: 2
      })
 
    const changeObj = () => {
        // 连续触发2次setObj(实际项目不会这样写,我这样写只是为了模拟连续触发2次setObj带来的问题)
        setObj({...obj, a: 2})
        setObj({...obj, b: 3}) 
    }
   return (<div onClick={changeObj}>
          // 此时页面上显示的值为 {a: 1, b: 3}, 出现该问题的原因是因为useState是异步的,在第二次触发setObj时,obj还是没更新a之前的obj,所以出现该结果
            {JSON.stringify(obj)}
           </div>)
}

解决此情况的方式,就是在第二次触发时使用setObj((data) => ({...data, b: 3})) 这样的方式

import React, {useState} from 'react';
 
export default () => {
    const [obj, setObj] = useState({
        a: 1,
        b: 2
      })
 
    const changeObj = () => {
        // 连续触发2次setObj(实际项目不会这样写,为了模拟情况)
        setObj({...obj, a: 2})
        // data标识存储的是更新a后的对象,用这样的方式可以解决连续触发2次带来的问题
        setObj((data) => ({...data, b: 3})) 
    }
   return (<div onClick={changeObj}>
          // 此时页面上显示的值为 {a: 2, b: 3}
            {JSON.stringify(obj)}
           </div>)
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅谈React底层实现原理

    浅谈React底层实现原理

    本文主要介绍了浅谈React底层实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 浅析JS中什么是自定义react数据验证组件

    浅析JS中什么是自定义react数据验证组件

    我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题。这篇文章主要介绍了js中什么是自定义react数据验证组件,需要的朋友可以参考下
    2018-10-10
  • react quill中图片上传由默认转成base64改成上传到服务器的方法

    react quill中图片上传由默认转成base64改成上传到服务器的方法

    这篇文章主要介绍了react quill中图片上传由默认转成base64改成上传到服务器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • React大文件分片上传原理及方案

    React大文件分片上传原理及方案

    前端进行大文件分片上传的方案几乎都是利用Blob.prototype.slice方法对文件进行分片,用数组将每一个分片存起来,最后将分片发给后端,本文给大家介绍React大文件分片上传方案,感兴趣的朋友跟随小编一起看看吧
    2023-08-08
  • 浅谈对于react-thunk中间件的简单理解

    浅谈对于react-thunk中间件的简单理解

    这篇文章主要介绍了浅谈对于react-thunk中间件的简单理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • React中的JSX  { }的使用详解

    React中的JSX  { }的使用详解

    这篇文章主要介绍了React中的JSX{ }的使用,React使用JSX来替代常规的JavaScript,JSX可以理解为的JavaScript语法扩展,它里面的标签申明要符合XML规范要求,对React JSX使用感兴趣的朋友一起看看吧
    2022-08-08
  • 记一个React.memo引起的bug

    记一个React.memo引起的bug

    memo可以自己决定是否更新,但它是一个函数组件而非一个类,本文主要介绍了React.memo引起的bug,具有一定的参考价值,感兴趣的可以了解一下
    2022-03-03
  • React中使用react-json-view展示JSON数据的操作方法

    React中使用react-json-view展示JSON数据的操作方法

    react-json-view是一个用于显示和编辑javascript数组和JSON对象的React组件,本文给大家分享React中使用react-json-view展示JSON数据的操作方法,感兴趣的朋友一起看看吧
    2023-12-12
  • React生命周期函数图解介绍

    React生命周期函数图解介绍

    生命周期函数指在某一时刻组件会自动调用并执行的函数。React每个类组件都包含生命周期方法,以便于在运行过程中特定的阶段执行这些方法
    2022-11-11
  • 使用react-router4.0实现重定向和404功能的方法

    使用react-router4.0实现重定向和404功能的方法

    本篇文章主要介绍了使用react-router4.0实现重定向和404功能的方法,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08

最新评论