Reputation: 39
I have coded a simple React application that tracks feedback, the whole code for the application is below:
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = () => {
// save clicks of each button to its own state
const [good, setGood] = useState(0)
const [neutral, setNeutral] = useState(0)
const [bad, setBad] = useState(0)
const [all, setAll] = useState(0)
const [average, setAverage] = useState(0)
const [positive, setPositive] = useState(0)
const handleGood = () => {
setGood(good + 1)
setAll(all + 1)
setAverage((average + 1) /(all))
setPositive(good/all)
}
const handleNeutral = () => {
setNeutral(neutral + 1)
setAll(all + 1)
setAverage((average) / (all))
}
const handleBad = () => {
setBad(bad + 1)
setAll(all + 1)
setAverage((average - 1) / (all))
}
return (
<div>
<h1>give feedback</h1>
<button onClick={handleGood}>good</button>
<button onClick={handleNeutral}>neutral</button>
<button onClick={handleBad}>bad</button>
<h3>statistics</h3>
<div>good {good}</div>
<div>neutral {neutral}</div>
<div>bad {bad}</div>
<div>all {all}</div>
<div>average {average}</div>
<div>positive {positive}</div>
</div>
)
}
ReactDOM.render(<App />,
document.getElementById('root')
)
From the initial state if I click the "good" button once, the AVERAGE comes out to Infinity and POSTIVE comes out to Nan, I'm really confused why the application is behaving like this, is this because I'm using multiple setState methods in the click event handlers, and they are synchronous functions? Is there an important concept that I'm missing here when using useState hooks.
Upvotes: 0
Views: 202
Reputation: 64657
and they are synchronous functions
Sort of - they don't return promises, but when you do:
setAll(all + 1)
setAverage((average) / (all))
all
won't have updated until the next render cycle. What you need to do is more like:
const newAll = all + 1
setAll(newAll);
setAverage(average/newAll);
if you want to use the updated value immediately after setting it.
Upvotes: 2