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

目录
  • React Hook中useState更新延迟
  • 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>)
}

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

(0)

相关推荐

  • react纯函数组件setState更新页面不刷新的解决

    目录 问题描述: 原因分析: 解决方案: 补:react中,hooks钩子时useState更新不渲染组件的问题 问题描述: const [textList, setTextList] = useState(原数组); setTextList(新数组); 当修改原数组时,如果原数组是个深层数组(不只一层),使用setTextList修改时,不会触发页面刷新 原因分析: 这个涉及到可变对象he不可变对象的知识,在vue和react中,如果更新可变对象时,可能会引起视图更新,这是因为,vue和rea

  • 详解React setState数据更新机制

    为什么使用setState 在React 的开发过程中,难免会与组件的state打交道.使用过React 的都知道,想要修改state中的值,必须使用内部提供的setState 方法.为什么不能直接使用赋值的方式修改state的值呢?我们就分析一下,先看一个demo. class Index extends React.Component { this.state = { count: 0 } onClick = () => { this.setState({ count: 10 }) } re

  • 关于react useState更新异步问题

    目录 react useState更新异步 记useState异步更新小坑 问题点 react useState更新异步 当我们使用react中useState这个hook时候,如下 const [page, setPage] = useState(1); const handlerClick = (e)=>{     setPage(e.current);     console.log(page); } 当我打印page时候,此时page还是1,因为useState的更新是异步的,这和rea

  • 解决react中useState状态异步更新的问题

    目录 疑惑 状态异步更新带来的问题 问题示例 问题解决 类组件的解决方案 函数组件的解决方案 其他解决方案 结尾 疑惑 相信刚开始使用react函数组件的小伙伴也遇到过一个坑,就是 useState 更新状态是异步更新的,但是react 并没有提供关于这个问题的解决方案.那我们能否使用自己的方法来解决这个问题呢?答案肯定是可以的. 状态异步更新带来的问题 就拿一个比较常见的场景来说.在react项目中,我们想在关闭对话框后再去处理其他业务.但是 useState 的状态是异步更新的.我们通过se

  • react如何获取state的值并更新使用

    目录 react获取state值并更新使用 在视图层处理 在model层处理 react中state基本使用 有状态组件和无状态组件 state的基本使用 setState修改状态 从JSX中抽离事件处理程序 事件绑定this指向 react获取state值并更新使用 react获取state的值并且修改分为两种情况: 在视图层处理 //在 state 中饭设置初始值 state={       name:'',       age:''  } //通过 控制一个事件触发然后setState 去

  • ReactHooks批量更新state及获取路由参数示例解析

    目录 一.如何批量更新 控制台输出 二.Hooks如何获取路由参数 执行效果 一.如何批量更新 在[Hooks]中如果单独的进行状态的更新可能会导致页面的多次渲染: import { useState } from 'react'; import { unstable_batchedUpdates } from 'react-dom';//批量更新状态时使用 import React from 'react'; const Example = () => { const [count, setC

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

    目录 React Hook中useState更新延迟 React Hook useState连续更新对象问题 React Hook中useState更新延迟 方法一:去掉useEffect的第二个参数 例如以下代码 错误实例 const[zoom, setZoom] = useState(0); useEffect(() = >{     document.getElementById('workspace-content').addEventListener('mousewheel', scr

  • React Hook中的useState函数的详细解析

    useState => 让函数组件具有维持状态的能力useState 这个 Hook 是用来管理 state 的,它可以让函数组件具有维持状态的能力.即在一个函数组件的多次渲染之间,这个 state 是共享的. Hooks 的最大的作用就是可以让你在不编写class的情况下使用state以及其他的 React 特性 useState的详细解析 在上一篇文章中, 我用到useState来让大家体验一下hooks函数 import { memo, useState } from "react&

  • React Hook中的useEffecfa函数的使用小结

    目录 useEffect的详细解析 useEffecf基本使用 清除副作用(Effect) 使用多个useEffect useEffect性能优化 useEffect的详细解析 useEffecf基本使用 书接上文, 上一篇文章我们讲解了State Hook, 我们已经可以通过这个hook在函数式组件中定义state 我们知道在类组件中是可以有生命周期函数的, 那么如何在函数组件中定义类似于生命周期这些函数呢? Effect Hook 可以让你来完成一些类似于class中生命周期的功能; 事实上

  • React函数式组件Hook中的useState函数的详细解析

    目录 前言 一.什么是函数式组件 二.useState 前言 公司项目需要使用react,而函数式组件也是官方比较推荐的!!!所以学习hooks是很重要的. 一.什么是函数式组件 纯函数组件有以下特点: 没有状态 没有生命周期 没有 this 因存在如上特点,使得纯函数组件只能做UI展示的功能, 涉及到状态的管理与切换就不得不用到类组件或者redux. 但因为简单的页面也是用类组件,同时要继承一个React实例,使得代码会显得很重. 以前我们可以使用class来声明一个组件,其实使用functi

  • 示例详解react中useState的用法

    useState useState 通过在函数组件里调用它来给组件添加一些内部 state.React 会在重复渲染时保留这个 state.useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数.它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并. 接下来通过一个示例来看看怎么使用 useState. 有这么一个需求:需要在 iframe 中加载外部网页. 初始的代码我们通过

  • React中useState的使用方法及注意事项

    目录 一.基本使用 第一个问题:setCount修改值时它是同步还是异步? 第二个问题:连续调用 setCount会发生什么? 二.注意事项 1.复杂变量的修改 2.异步操作获取更新的值 总结 一.基本使用 useState是 react 提供的一个定义响应式变量的 hook 函数,基本语法如下: const [count, setCount] = useState(initialCount) 它返回一个状态和一个修改状态的方法,状态需要通过这个方法来进行修改: initialCount 是我们

  • React函数式组件Hook中的useEffect函数的详细解析

    目录 前言 useEffect的作用 useEffect的使用? 1.class组件 2.函数式组件 总结 前言 React函数式编程没有生命周期,因此需要借助useEffect来实现. useEffect的作用 发ajax请求获取数据 设置订阅/获取定时器 手动更改真实DOM useEffect的使用? 1.class组件 在class组件中可以使用生命周期函数,知道组件触发的过程. 代码如下(示例): import React, { Component } from 'react' expo

  • 解决React hook 'useState' cannot be called in a class component报错

    目录 总览 函数组件 类组件中使用setState() 总览 当我们尝试在类组件中使用useState 钩子时,会产生"React hook 'useState' cannot be called in a class component"错误.为了解决该错误,请将类组件转换为函数组件.因为钩子不能在类组件中使用. 这里有个例子用来展示错误是如何发生的. // App.js import {useState, useEffect} from 'react'; class Example

随机推荐