React在定时器中无法获取状态最新值的问题

目录
  • 在定时器中无法获取状态最新值
    • 问题原因
    • 问题解决
  • ReactHook hooks和定时器产生的bug
    • 问题1
    • 解决方案

在定时器中无法获取状态最新值

在做轮播图组件时发现了一个问题,在setInterval中无法通过状态直接获取最新值,如:

const [rightTransform, setRightTransform] = useState(pictureSize);

const autoPlay = () => {        //普通轮播自动播放
    timer.current = setInterval(() => {
      let oldState = rightTransform;
      console.log('老状态', oldState)			//始终只会打印初始的pictureSize
      setRightTransform(o => {
        const newState = JSON.parse(JSON.stringify(o));
        return newState >= (renderImgList.length) * pictureSize ? 0 : newState + pictureSize
      })
	}, 1000);
}

问题原因

定时器一直都没有被清除,因此获取的状态始终是定时器被创建时候的状态。

问题解决

从代码和图片可以看到,定时器中打印的状态永远都是初始值,后面所改变的值虽然更新了,页面也发生了变化,但是我们从log中无法获取到实时状态。

解决办法很简单:

第一种,就是在setState中获取上一次状态,因为useState hooks提供了记录上一次状态的缓存回调,可以在这个回调中获取上一轮状态

如图:

timer.current = setInterval(() => {
      let oldState = rightTransform;
      setRightTransform(o => {
        console.log('在setState中的老状态', o)
        const newState = JSON.parse(JSON.stringify(o));
        return newState >= (renderImgList.length) * pictureSize ? 0 : newState + pictureSize
      })
      console.log('直接打印老状态', oldState)
}

ReactHook hooks和定时器产生的bug

问题1

使用定时器改变state,state的值并不是最新值

例:

 const _onClick = function ()
 {
   setInterval(() => {
     console.log(value);
     setValue(value + 1);
   },1000)
 }

产生原因:因为每次setValue后会重新创建函数,由于并没有及时清理掉setInterval,setInterval执行的上下文环境都是第一次创建本函数式组件的上下文(所以value值不会超过1)

解决方案

方案一:

setInterval(() => {
     console.log(value);
     setValue(v=>v+1);      函数式的setValue会保存上一次的值,所以会取得最新值,该方式指定state该如何改变而不用引用当前state
   },1000)

方案二:

useEffect(() => {
     const id = setInterval(() => {
         valf.current++;    不一定是ref操作,正常set操作即可
       }, 1000);
       return () => clearInterval(id);
   }, []);

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

(0)

相关推荐

  • ahooks解决React闭包问题方法示例

    引言 本文是深入浅出 ahooks 源码系列文章的第三篇,这个系列的目标主要有以下几点: 加深对 React hooks 的理解. 学习如何抽象自定义 hooks.构建属于自己的 React hooks 工具库. 培养阅读学习源码的习惯,工具库是一个对源码阅读不错的选择. 注:本系列对 ahooks 的源码解析是基于 v3.3.13.自己 folk 了一份源码,主要是对源码做了一些解读,可见 详情. 系列文章: 大家都能看得懂的源码 ahooks 整体架构篇 如何使用插件化机制优雅的封装你的请求

  • React useEffect异步操作常见问题小结

    目录 三个常见的问题: 一.react hooks发异步请求 二.如何在组件加载的时候发起异步任务 三.如果在响应回来之前组件被销毁了会怎样? 四.如何在组件交互时发起异步任务 为什么两种写法会有差异呢? 五.其他陷阱 总结 useEffect 和异步任务搭配使用的时候会遇到的一些坑总结. 三个常见的问题: 1.如何在组件加载的时候发起异步任务 2.如何在组件交互的时候发起异步任务 3.其他陷阱 一.react hooks发异步请求 1.使用useEffect发起异步任务,第二个参数使用空数组可

  • 浅谈React之状态(State)

    在React当中,当你更新组件的state,然后新的state就会重新渲染到页面中.在这个时候不需要你操作任何DOM.你也可以认为组件在React当中是一个状态机(State Machines).当用户进行操作时会实现不同的状态,然后再渲染到你的页面中,让你的页面与数据始终保持一致. 如何定义State 定义一个合适的State,是正确创建组件的第一步.State必须能代表一个组件UI呈现的完整状态集,即组件的任何UI改变,都可以从State的变化中反映出来:同时,State还必须是代表一个组件

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

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

  • React在定时器中无法获取状态最新值的问题

    目录 在定时器中无法获取状态最新值 问题原因 问题解决 ReactHook hooks和定时器产生的bug 问题1 解决方案 在定时器中无法获取状态最新值 在做轮播图组件时发现了一个问题,在setInterval中无法通过状态直接获取最新值,如: const [rightTransform, setRightTransform] = useState(pictureSize); const autoPlay = () => { //普通轮播自动播放 timer.current = setInte

  • Android中实时获取音量分贝值详解

    基础知识 度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB).这是一个无纲量的相对单位,计算公式如下: 分子是测量值的声压,分母是参考值的声压(20微帕,人类所能听到的最小声压).因此日常中说道声音强度是多少多少分贝时,都是默认了一个很小的参考值的. 而Android设备传感器可以提供的物理量是场的幅值(amplitude),常用下列公式计算分贝值: 从SDK中读取了某段音频数据的振幅后,取最大振幅或平均振幅(可以用平方和平均,或绝对值的和平均),代入上述公式的A1. 现在问题

  • SpringMVC中如何获取@PathVariable的值

    目录 如何获取@PathVariable的值 一.地址:**/{id} 二.方式 springmvc 使用@PathVariable时,应该注意点什么? 一.使用@PathVariable的转变过程 二.个人总结 如何获取@PathVariable的值 一.地址:**/{id} @RequestMapping(value = "/del/{id}", method = RequestMethod.GET) public void del(HttpServletRequest reque

  • python中dict获取关键字与值的实现

    目录 dict获取关键字与值 values() items() 字典dict(关键字对应的值为list) 方法一 方法二 dict获取关键字与值 values() >>> d {'p': 34, 'l': 54, 'b': 88} >>> for value in d.values(): ...     print(value) ... 34 54 88 items() >>> for key,value in d.items(): ...     p

  • springboot获取properties属性值的多种方式总结

    目录 获取properties属性值方式总结 1. 除了默认配置在 application.properties的多环境中添加属性 2. 使用之前在spring中加载的value值形式 3. 也可以使用springboot里面的Environment 直接取值 4. 如果是自己新建的一个properties文件 获取多个自定义属性值 比如在application中自定义属性 获取properties属性值方式总结 spring boot 在多环境情况下我们需要根据不同的获取不一样的值, 我们会配

  • React和Vue中监听变量变化的方法

    React 中 本地调试React代码的方法 yarn build 场景 假设有这样一个场景,父组件传递子组件一个A参数,子组件需要监听A参数的变化转换为state. 16之前 在React以前我们可以使用 componentWillReveiveProps 来监听 props 的变换 16之后 在最新版本的React中可以使用新出的 getDerivedStateFromProps 进行props的监听, getDerivedStateFromProps 可以返回 null 或者一个对象,如果

  • 基于React Context实现一个简单的状态管理的示例代码

    目录 前言 封装一个父组件用来包裹其他子组件 子组件如何获取数据呢 class Component 方式 context.Consumer useContext 总结 参考 前言 在大多数情况下,我们开发项目都需要一个状态管理,方便我们在全局共享状态库,在React生态里比较流行的几个库 redux.mobx.recoil 但是对于小项目,我们完全可以自己封装一个状态管理,减少一个包的安装就可以减小打包以后的项目体积. 主要分两步: 封装一个顶层组件提供数据 子组件获取数据和更新数据 封装一个父

  • React Hooks钩子中API的使用示例分析

    目录 hooks是什么 Hooks的作用 使用Hooks组件前后开发模式的对比 Hooks使用策略 为什么要有Hooks useState useEffect使用 useEffect依赖项 使用情景 useMemo使用 useMemo缓存组件方式 useMemo和useEffect的区别 useCallback使用 useContext使用 useRef使用 为什么在函数组件中无法使用ref 如何在类组件中使用ref属性 自定义hooks hooks是什么 hooks理解字面意思就是钩子,是一些

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

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

  • React组件封装中三大核心属性详细介绍

    目录 1.介绍 2.state 概念 演示 3.props 概念 props与state区别 4.refs 概念 refs种类 5.父子组件 什么是父子组件 父子组件之间传值 1.介绍 React组件中默认封装了很多属性,有的是提供给开发者操作的,其中有三个属性非常重要:state.props.refs. 2.state 概念 state是类组件的一个默认属性,用于标识类组件的状态,负责更新UI,让页面动态变化,当state变化时,组件将被重新渲染. 函数组件没有对象属性(babel默认开启了局

随机推荐