React 在异步回调中记住值

React memorizes value in async callback

React 意外保留了 React.useState(...) 生成的变量的旧值。我按下按钮 [1],然后按下 [2]。在 3000 毫秒内,我希望在警报消息中看到 "null",但仍然看到 "42"。 将 handleDisplay 包装成 React.useCallback 并依赖于 [val] 没有帮助。

function App() {
    const [val, setVal] = React.useState(42)

    const handleHide = () => {
        setVal(null)
    }

    const handleDisplay = () => {
        setTimeout(() => {
            alert(val)
        }, 3000)
    }

    return (
        <div>
            <p>VAL: {val ? val : 'null'}</p>
            <button onClick={handleDisplay}>[1] display value with delay</button>
            <button onClick={handleHide}>[2] hide immediately</button>
        </div>
    )
}

同时 — 页面上的值(通过 VAL: { val ? val : 'null' } 呈现)是正确的,它是预期的 "null"。 关于我做错了什么以及如何在我的 alert(...) 中获得 "null" 的任何想法?

P.S。这是一个带有实例的沙箱 https://codesandbox.io/s/react-usestate-bug-24ijj

在第一次渲染时,val 只是一个常数,其值为 42,永远不会改变。这是单击按钮 1 时传递给 setTimeout 的值。在 3 秒过去之前单击按钮 2 将导致新渲染,其中 val 的新实例具有值 null,但这不会影响第一次渲染中绑定的值.您可能想阅读 useEffect 挂钩。 Dan Abramov 在这里有一篇很棒但很长的文章,其中只提到了这个问题:https://overreacted.io/a-complete-guide-to-useeffect/