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

React JS中useReducer Hook异常 控制台重复打印问题咨询

React useReducer 触发时控制台重复打印两次的原因

造成这个现象有两个核心原因:

  • 开发环境React严格模式的纯函数校验机制
    React 18+ 版本中,如果根组件被<React.StrictMode>包裹,开发环境下会主动对reducer、组件渲染逻辑、状态初始化函数这类要求为纯函数的逻辑执行双调用,目的是提前检测代码里的非预期副作用。该行为仅在开发环境生效,生产环境构建后会自动移除,不会产生额外性能消耗或逻辑异常。
  • Reducer写法违反纯函数规则,触发状态更新异常
    代码中使用state.count++、state.count--的后缀运算符更新状态,会直接修改传入的原始state对象,违反了useReducer要求reducer为纯函数的规则:禁止修改入参state,必须返回全新的状态对象。直接篡改原state会导致React状态比对逻辑异常,结合严格模式的双调用机制,就会出现控制台重复打印、计数结果不符合预期的问题。
修复方式

将reducer中的状态更新改为不可变更新逻辑,不要直接修改原state:

import React, {useReducer} from 'react';

const Counter = () => {
    const initialState = { count: 0 }

    const reducer = (state, action) => {
      switch(action.type) {
        case 'INC':
            console.log(state)
            // 基于原state值计算新值,返回全新对象,不修改原state
            return { count: state.count + 1 }
        case 'DEC':
            console.log(state)
            return { count: state.count - 1 }
        default:
            return state
    }
}

const [componentState, dispatch] = useReducer(reducer, initialState);

return (
    <>
        {componentState.count}
        <button onClick={() => dispatch({type: 'INC'})}>Increase</button>
        <button onClick={() => dispatch({type: 'DEC'})}>Decrease</button>
    </>
)
}

export default Counter;

提示:不建议为了消除开发环境的双调用日志直接移除<React.StrictMode>,严格模式可以提前帮你定位大量隐蔽的React写法问题,只要保证reducer、渲染逻辑符合纯函数要求,双调用不会影响最终业务逻辑的运行结果。

问题复现参考截图:
控制台打印效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:27:17