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

React中使用useReducer实现计数器时增减操作出现NaN问题排查求助

问题分析与解决方案

嘿,我懂你遇到NaN问题的烦躁——咱们直接揪出根源,让计数器正常跑起来!

核心问题:State结构不匹配

你在初始化useReducer的state时,把初始计数存在了initialCount属性里:

{ initialCount: initialCount }

但在reducer逻辑和Counter组件中,你访问的却是state.count。这就导致初始状态下state.count是undefined,当你执行加减操作时,undefined + 1或者undefined -1都会得到NaN,后续所有操作都会基于这个NaN,结果自然一直是NaN。

修复步骤

只需要把初始化的state结构改成{ count: initialCount },让reducer和组件访问的属性保持一致:

// 修改useReducer的初始state
const [state, dispatch] = React.useReducer(
  (state, action) => {
    const change = action.step ?? step
    switch (action.type) {
      case 'increment': {
        return { ...state, count: state.count + change }
      }
      case 'decrement': {
        return { ...state, count: state.count - change }
      }
      default: {
        throw new Error(`Unhandled action type:${action.type}`)
      }
    }
  },
  { count: initialCount } // 这里把initialCount改成count
)

额外优化建议

  1. useCallback的依赖简化:dispatch是useReducer返回的稳定引用,不需要放进useCallback的依赖数组里,所以可以写成:
const increment = React.useCallback(() => dispatch({ type: 'increment' }), [])
const decrement = React.useCallback(() => dispatch({ type: 'decrement' }), [])

这样能避免不必要的函数重复创建。

  1. State结构一致性:保持state的属性名统一,后续维护起来会更清晰。

修复后的完整代码

import * as React from 'react';
const CounterContext = React.createContext();
function CounterProvider({ step = 1, initialCount = 0, ...props }) {
  const [state, dispatch] = React.useReducer(
    (state, action) => {
      const change = action.step ?? step
      switch (action.type) {
        case 'increment': {
          return { ...state, count: state.count + change }
        }
        case 'decrement': {
          return { ...state, count: state.count - change }
        }
        default: {
          throw new Error(`Unhandled action type:${action.type}`)
        }
      }
    },
    { count: initialCount } // 修正此处的state属性名
  )
  // 简化useCallback的依赖
  const increment = React.useCallback(() => dispatch({ type: 'increment' }), [])
  const decrement = React.useCallback(() => dispatch({ type: 'decrement' }), [])
  const value = { increment, decrement, state }
  return <CounterContext.Provider value={value} {...props} />
}
function useCounter() {
  const context = React.useContext(CounterContext)
  if (context === undefined) {
    throw new Error('useCounter must be used within CounterProvider')
  }
  return context
}
function Counter() {
  const { state, increment, decrement } = useCounter();
  console.log(state, 'inc ', increment, 'dec ', decrement)
  return (
    <div>
      <button onClick={decrement}>-</button>
      <button onClick={increment}>+</button>
      <div>Current Count: {state.count}</div>
    </div>
  )
}
function App() {
  return (
    <CounterProvider>
      <Counter />
    </CounterProvider>
  )
}
export default App

这样修改后,计数器的加减操作就能正常计算数值,不会再出现NaN了!

内容的提问来源于stack exchange,提问作者Fares_Essayeh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 10:47:35