React中计算两个state值的平均值时出现NaN该如何解决?
问题根源
- 计算
average时使用了未更新的旧状态值:第一次触发点击事件时,你调用的还是初始的stats.all(值为0),除以0的运算结果就是NaN。而且你在构造newStats时已经更新了all、good/bad的数值,但计算平均值时没有用到这些新值,天生就会慢一拍出现状态不同步。 - 冗余的派生状态:
all、average、positive都属于可以通过good、neutral、bad三个基础状态直接计算出来的派生值,不需要单独存储在state中,额外存储反而会提升维护成本,容易出现同步错误。
最优修改方案
直接简化state结构,只保留三个基础统计值,所有派生值在渲染时实时计算,从根源避免状态不同步和除0异常,修改后的代码如下:
import React, { useState } from "react" const App = () =>{ // 仅保留基础状态 const [stats, setClicks] = useState({good:0, neutral:0, bad:0}) const handleGood = () => { setClicks(prev => ({...prev, good: prev.good + 1})) } const handleBad = () => { setClicks(prev => ({...prev, bad: prev.bad + 1})) } const handleNeutral = () => { setClicks(prev => ({...prev, neutral: prev.neutral + 1})) } const Button = ({handleClick, text}) => { return <button onClick={handleClick}>{text}</button> } // 实时计算派生值 const all = stats.good + stats.neutral + stats.bad const average = all === 0 ? 0 : (stats.good - stats.bad) / all const positive = all === 0 ? 0 : (stats.good / all) * 100 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: {all}</p> <p>average: {average}</p> <p>positive: {positive}%</p> </div> ) } export default App
如果确实需要把派生值存在state中,修改时要注意使用更新后的新值计算,同时提前判断除0场景:
const handleGood=()=>{ const newGood = stats.good + 1 const newAll = stats.all + 1 const newAverage = newAll === 0 ? 0 : (newGood - stats.bad) / newAll const newStats={ ...stats, all: newAll, good: newGood, average: newAverage, } setClicks(newStats) }
内容的提问来源于stack exchange,提问作者codingKale
相关产品推荐
相关产品推荐

