根据之前的几个状态更新反应状态

问题描述 投票:0回答:1

假设我有两种反应状态:

a
b

const [a, setA] = useState(2)
const [b, setB] = useState(10)

我想添加一个按钮,根据它们之前的值更新它们:

function calculate() {
    setA(a * b)
    setB(b / a)
}

然后我想再添加一个按钮来执行

calculate
函数两次。

function calculate2times() {
    calculate()
    calculate()
}

当然我知道在这里我会遇到状态错误,因为反应状态更新是异步的。但是如果我按照以下方式更新

calculate
函数,我仍然会得到错误的结果:

function calculate() {
    setA((a) => a * b)
    setB((b) => b / a)
}

现在每个变量的更新都使用其自身的相关先前状态,但其他变量的值仍然是错误的。

如何使用

calculate2times
函数获得正确的结果?

完整代码:

import { useState } from "react";

const Example = () => {
    const [a, setA] = useState(2)
    const [b, setB] = useState(10)

    function reset () {
        setA(2)
        setB(10)
    }

    function calculate() {
        setA((a) => a * b)
        setB((b) => b / a)
    }

    function calculate2times() {
        calculate()
        calculate()
    }

    return (
        <div>
            <p>{`Current a: ${a}, Current b: ${b}`}</p>
            <button onClick={reset}>Reset</button>
            <button onClick={calculate}>Calculate</button>
            <button onClick={calculate2times}>Calculate two times</button>
        </div>
    );
}

export default Example;
javascript reactjs typescript react-hooks race-condition
1个回答
0
投票

在执行 setState 之前存储两者

function calculate() {
    let a2 = a
    let b2 = b
    setA(a2 * b2)
    setB(b2 / a2)
}

似乎是更简单的答案。您得到的错误结果是什么,因为更改状态会刷新页面,因此该功能可能无法完成或发生其他情况。您可以使用 e.preventDefault() 来避免这种情况,但您需要首先将 e 或事件传递给您的函数。

© www.soinside.com 2019 - 2024. All rights reserved.