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

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

相关推荐
编码七号2 分钟前
【axios取消请求】如何在token过期后取消未响应的请求
java·前端·javascript
张开心_kx3 分钟前
面试官又问我是否了解React的单向数据流
前端·javascript·react.js
Web漫游5 分钟前
🔥2025年了你还不会使用Vue3?
javascript·vue.js
残轩6 分钟前
Win10 家庭版 Docker 环境搭建详解(基于 WSL2)
前端·后端·docker
palpitation977 分钟前
Flutter分解布局选择辅助方法还是Widget?
前端
工呈士8 分钟前
HTML响应式网页设计与跨平台适配
前端·html
作曲家种太阳9 分钟前
第六章节 响应式的 computed 实现【手摸手带你实现一个vue3】
前端
腊月廿二10 分钟前
跨项目频繁切换node版本号(nvm-windows)
前端
策码12 分钟前
MutationObserver监听网页二次渲染和子节点变化
前端·javascript
前端大白话13 分钟前
前端必知!HTML中`<a>`标签target属性全攻略:新窗口、当前窗口、指定框架一网打尽
前端·架构·html