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); // 直接传递更新后的值
  }
};

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

相关推荐
前端百草阁8 分钟前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜8 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4049 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish10 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple10 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five11 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序11 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54111 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
酷酷的威朗普12 分钟前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5
前端每日三省13 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript