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
相关产品推荐
相关产品推荐

