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

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

相关推荐
2601_963771376 小时前
WordPress SEO Guide: Boost Rankings Without Technical Jargon
前端·php
李顿波6 小时前
Chrome 扩展程序 MV3 架构组件概览
前端·chrome·浏览器插件
KingCodeHan6 小时前
ESLint 完全指南:从入门到精通
前端
GHL2842710907 小时前
安装chrome浏览器
前端·chrome
kisshyshy7 小时前
从0到1彻底理解流式输出:先读懂Vue的“乐高积木”,再拧开LLM的“数据水龙头”
javascript·vue.js·人工智能
谙忆10247 小时前
WebCodecs 实战:用 ImageDecoder 和 VideoFrame 在浏览器里做硬件加速的帧处理
前端
JerrySir7 小时前
密码没泄露,2FA 也没失效:Chrome 146 为什么还要让 Cookie“搬不走”?
前端
小蚂蚁i7 小时前
React Hooks 原理深度解析:从会用到真正懂
前端·react.js
触底反弹7 小时前
Vue 实战:手把手教你实现 ChatGPT 同款打字机效果
前端·javascript·人工智能
BreezeJiang7 小时前
Vue 3 流式输出实战:ReadableStream + DeepSeek API 实现打字机对话
前端