React——setState 新旧值复用问题

异步状态更新获取新值问题

问题

js 复制代码
const updateFrameRange = (frameNumber, rangeValue) => {
    //
    const startFrame = Math.max(frameNumber - rangeValue.before, 1);
    const endFrame = Math.min(frameNumber + rangeValue.after, maxFrame);
console.log(frameNumber,rangeValue)
    const newFrameRange = Object.values(Data?.frames || {})
      .slice(startFrame - 1, endFrame)
      .map((frame) => frame.timestamp);
    setFrameRange(newFrameRange);
  };

  const handleFrameRangeBeforeChange = (e) => {
    const value = parseInt(e.target.value, 10);
    if (!isNaN(value) && value >= 0) {
      setFrameRangeValue((prev) => ({ ...prev, before: value }));
      updateFrameRange(frameNumber, frameRangeValue);
    }
  };

  const handleFrameRangeAfterChange = (e) => {
    const value = parseInt(e.target.value, 10);
    if (!isNaN(value) && value >= 0) {
      setFrameRangeValue((prev) => ({ ...prev, after: value }));
      updateFrameRange(frameNumber, frameRangeValue);
    }
  };

这一块代码updateFrameRange每次获取到的第二个参数都是上一个状态的旧值,我想立马获取到frameRangeValue更新后的新值.

解决

setFrameRangeValue 是异步的,所以当你在状态更新后立即调用 updateFrameRange 时,frameRangeValue 仍然是旧的值。为了解决这个问题,你可以先计算出新的值,然后将其传递给 updateFrameRange,而不是依赖尚未更新的状态值。

你可以这样修改代码,确保 updateFrameRange 使用的是最新的值:

复制代码
1.	在 handleFrameRangeBeforeChange 和 handleFrameRangeAfterChange 中,先计算新的 frameRangeValue,然后再分别传递给 setFrameRangeValue 和 updateFrameRange。
2.	这样做可以确保 updateFrameRange 使用的是刚计算出的新值,而不是等待异步状态更新完成。
js 复制代码
const updateFrameRange = (frameNumber, rangeValue) => {
  const startFrame = Math.max(frameNumber - rangeValue.before, 1);
  const endFrame = Math.min(frameNumber + rangeValue.after, maxFrame);

  const newFrameRange = Object.values(Data?.frames || {})
    .slice(startFrame - 1, endFrame)
    .map((frame) => frame.timestamp);
    
  setFrameRange(newFrameRange);
};

const handleFrameRangeBeforeChange = (e) => {
  const value = parseInt(e.target.value, 10);
  if (!isNaN(value) && value >= 0) {
    // 先计算新的 frameRangeValue
    const newRangeValue = { ...frameRangeValue, before: value };
    setFrameRangeValue(newRangeValue);
    updateFrameRange(frameNumber, newRangeValue); // 直接传递更新后的值
  }
};

const handleFrameRangeAfterChange = (e) => {
  const value = parseInt(e.target.value, 10);
  if (!isNaN(value) && value >= 0) {
    // 先计算新的 frameRangeValue
    const newRangeValue = { ...frameRangeValue, after: value };
    setFrameRangeValue(newRangeValue);
    updateFrameRange(frameNumber, newRangeValue); // 直接传递更新后的值
  }
};

所以应该尽量避免依赖异步状态更新完成。

相关推荐
曲折11 分钟前
Cesium-气象要素PNG色斑图叠加
前端·cesium
Forever7_18 分钟前
Electron 淘汰!新的桌面端框架 更强大、更轻量化
前端·vue.js
不会敲代码127 分钟前
前端组件化样式隔离实战:React CSS Modules、styled-components 与 Vue scoped 对比
css·vue.js·react.js
Angelial28 分钟前
Vue3 嵌套路由 KeepAlive:动态缓存与反向配置方案
前端·vue.js
jiayu1 小时前
Angular学习笔记24:Angular 响应式表单 FormArray 与 FormGroup 相互嵌套
前端
jiayu1 小时前
Angular6学习笔记13:HTTP(3)
前端
小码哥_常1 小时前
Kotlin抽象类与接口:相爱相杀的编程“CP”
前端
evelynlab1 小时前
Tapable学习
前端
进击的尘埃1 小时前
Vue3 响应式原理:从 Proxy 到依赖收集,手撸一个迷你 reactivity
javascript
willow1 小时前
JavaScript数据类型整理1
javascript