You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:24:04