The following component is supposed to:
- Get a single letter from an api call
- Append it to the string and display it
Problem: when I press the button quickly a couple of times the string is only updated with 1 letter Expected result: The string gets updated with the same number of letters as button clicks, no matter how frequent the clicks are
I understand that the issue is that the closure keeps a reference to the old letters
variable that's in state.
But how do I solve this with hooks? I rewrote this to a class component and it worked there, but that's because this.state.letters
was not in a closure.
Press "Run code snippet" to test.
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>