Newbie here. Trying to learn React and I am currently trying to display the average=(good bad)/all
However, I keep getting NaN
which I am assuming I am getting because my state values are all 0. I am confused as to why this is because after calling setClicks(newStats)
I thought the stats are updated.
import React, { useState } from "react"
const App = () =>{
const [stats,setClicks] = useState({good:0,neutral:0,bad:0,all:0,positive:0,average:0})
const handleGood=()=>
{
const newStats={
...stats,
all: stats.all 1,
good:stats.good 1,
average: (stats.good - stats.bad)/stats.all,
}
setClicks(newStats)
console.log("Stats.good",stats.good)
console.log("Stats.bad",newStats.bad)
console.log("Stats.all",stats.all)
}
const handleBad=()=>
{
const newStats= {
...stats,
bad: stats.bad 1,
all: stats.all 1,
average: (stats.good - stats.bad)/stats.all,
}
setClicks(newStats)
}
const handleNeutral =() =>
{
const newStats={
...stats,
neutral:stats.neutral 1,
all: stats.all 1,
average: (stats.good - stats.bad)/stats.all,
}
setClicks(newStats)
}
const Button =({handleClick,text})=>{
return(
<button onClick={handleClick}>{text}</button> )
}
return(
<div>
<h1>Give Feedback</h1>
<Button handleClick={handleGood} text="good"/>
<Button handleClick={handleNeutral} text="neutral"/>
<Button handleClick={handleBad} text="bad"/>
<br/>
<h2>Statistics</h2>
<p>good: {stats.good}</p>
<p>neutral: {stats.neutral}</p>
<p>bad: {stats.bad}</p>
<p>all:{stats.all}</p>
<p>average: {stats.average}</p>
<p>positive: {stats.positive}</p>
</div>
)
}
export default App
What is the best way to change state? How should this be done so NaN
does not appear?
CodePudding user response:
For the initial calculation of average, you need to use the updated values:
const handleGood= () => {
const newAll = stats.all 1;
const newGood = stats.good 1;
const newStats={
...stats,
all: newAll ,
good:newGood ,
average: (newGood - stats.bad)/newAll,
}
setClicks(newStats);
}
CodePudding user response:
You are getting NaN because you are dividing 0/0 and not calculating the average correctly. You should use new good, bad, ... values for average.
In this part of your code:
const newStats={
...stats,
all: stats.all 1,
good:stats.good 1,
average: (stats.good - stats.bad)/stats.all,
}
You are calculating average with the old values of all, good in your state.
By the way, adding Math.abs avoid getting a negative average value.
This is an updated version of your handleGood function.
const handleGood=()=>
{
const newAll = stats.all 1;
const newGood = stats.good 1;
const newAverage = Math.abs(newGood-stats.bad)/newGood
const newStats={
...stats,
all: newAll,
good:newGood,
average: newAverage,
}
setClicks(newStats)
console.log("Stats.good",newStats.good)
console.log("Stats.bad",newStats.bad)
console.log("Stats.all",newStats.all)
}