【问题标题】:React hooks - async setState update with old state because of closure [duplicate]React hooks - 由于关闭而使用旧状态异步更新 setState [重复]
【发布时间】:2020-05-21 20:09:17
【问题描述】:

以下组件应该:

  1. 从 api 调用中获取单个字母
  2. 将它附加到字符串并显示它

问题:当我快速按下按钮几次时,字符串仅更新为 1 个字母 预期结果:无论点击的频率如何,字符串都会更新为与按钮点击相同数量的字母

我了解问题在于闭包保留了对处于状态的旧 letters 变量的引用。 但是我如何用钩子解决这个问题?我将它重写为一个类组件并且它在那里工作,但那是因为this.state.letters 不在闭包中。

按“运行代码sn-p”进行测试。

function getRandomLetter() {
  return 'abcdefghijklmnopqrstuvwxyz'[new Date() % 26]
}

function apiCreateNextLetter() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(getRandomLetter())
    }, 1000)
  })
}

function Alphabet() {
  const [letters, setLetters] = React.useState('')

  function getNextLetter() {
    apiCreateNextLetter().then(nextLetter => {
      setLetters(letters + nextLetter)
    })
  }

  return (
    <div>
      <button onClick={getNextLetter}>
        Get next letter
      </button>
      <span>
        Letters: {letters}
      </span>
    </div>
  )
}

ReactDOM.render(<Alphabet />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script><div id="app"></div>

【问题讨论】:

标签: javascript reactjs closures react-hooks


【解决方案1】:

使用updater form...

setLetters(prevLetters => prevLetters + nextLetter)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 2019-05-22
    • 2021-11-13
    • 2020-05-12
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多