You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么React的useState hook赋值后无法立即获取最新值?如何修复?

问题原因

React的useState返回的状态更新方法是异步批量执行的,调用setResponse之后,React不会立刻修改当前作用域里selectedResponse变量的值,只会把状态更新请求加入队列,等当前整个onSubmitAnswer函数执行完成、触发组件重渲染之后,下一次渲染的selectedResponse才会拿到更新后的值。

你现在的代码中,setResponse调用后立刻打印selectedResponse、判断答案正误,用的都是当前这次渲染里的旧值,所以才会出现值滞后一次的现象。

修复方案

方案1:直接使用本次计算出的答案值做后续逻辑

你可以在坐标判断阶段就把本次计算出的答案存到本地变量里,后续打印、判断逻辑都用这个本地变量,需要同步到状态再调用setResponse即可,修改后的核心代码如下:

const onSubmitAnswer = () => {
    class Coordinate {
        x: number;
        y: number;

        constructor(x: number, y: number) {
            this.x = x;
            this.y = y;
        }
    }

    const width: number = box0.current.getBoundingClientRect().width;
    const height: number = box0.current.getBoundingClientRect().height;
    const box0Rect = box0.current.getBoundingClientRect();
    // 定义本地变量存储本次计算出的答案
    let currentAnswer: string|null = null;

    const boxCoordinates: Array<Coordinate> = [];
    for(let i=0;i<4;i++)
    {
        const data = eval(`box${i+1}`);
        boxCoordinates.push(new Coordinate(data.current.getBoundingClientRect().x, data.current.getBoundingClientRect().y));
    }     
    
    if(Math.abs(boxCoordinates[0].x - box0Rect.x) < width && Math.abs(boxCoordinates[0].y - box0Rect.y) < height)
    {
        currentAnswer = "A";
    }            
    else if(Math.abs(boxCoordinates[1].x - box0Rect.x) < width && Math.abs(boxCoordinates[1].y - box0Rect.y) < height)
    {
        currentAnswer = "B";
    }            
    else if(Math.abs(boxCoordinates[2].x - box0Rect.x) < width && Math.abs(boxCoordinates[2].y - box0Rect.y) < height)
    {               
        currentAnswer = "C";
    }            
    else if(Math.abs(boxCoordinates[3].x - box0Rect.x) < width && Math.abs(boxCoordinates[3].y - box0Rect.y) < height)
    {
        currentAnswer = "D";
    }

    // 同步到state
    setResponse(currentAnswer);
    // 后续逻辑全部用本地的currentAnswer
    console.log(currentAnswer);       

    if(correctResponse === currentAnswer) {
        console.log("ok");            
    }
    else {
        console.log("raspuns incorect");            
    }            
}

方案2:用useEffect监听状态变化执行后续逻辑

如果你必须等状态更新完成之后再执行逻辑,可以把打印、判断正误的逻辑抽到useEffect中,监听selectedResponse的变化,状态更新后会自动触发对应逻辑:

// 单独监听selectedResponse变化
useEffect(() => {
    if(selectedResponse === null) return;
    console.log(selectedResponse);
    if(correctResponse === selectedResponse) {
        console.log("ok");            
    } else {
        console.log("raspuns incorect");            
    }
}, [selectedResponse, correctResponse])

const onSubmitAnswer = () => {
    // 保留原来的坐标计算、setResponse逻辑即可,删掉后面的打印和判断部分
}

额外优化提示:你当前用eval获取box1到box4的ref的写法不推荐,建议把这四个ref统一存到数组里,直接遍历数组取值即可,避免eval带来的安全和性能问题。

内容的提问来源于stack exchange,提问作者user14399919

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:27:03