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

Redux Reducer状态更新异常:计数器点击报错求助

问题分析与修复

错误原因

核心问题出在counterReducer的职责范围与state结构不匹配:

  1. 你通过combineReducers({counter: counterReducer})将counterReducer绑定到store的state.counter字段,这意味着counterReducer应该管理单个数值(counter的当前值),但你给它的默认state设置成了整个initialState对象({counter:0})。
  2. 同时store的preloadedState是initialState={counter:0},这会覆盖counterReducer的默认state,让它的初始值变成0(数字类型)。
  3. 点击按钮触发action时,你在reducer里尝试展开数字类型的state(...state),并访问state.counter——数字没有counter属性,得到undefined,undefined+1会变成NaN,最终reducer返回{counter: NaN},导致store的state.counter变成一个对象。
  4. 最后在App组件里渲染selector.counter时,你把这个对象当作React子元素,触发了"Objects are not valid as a React child"错误。

修复方案(推荐)

调整counterReducer,让它专注管理单个数值:

修改counterReducer.js

import { DECREMENT_COUNTER, INCREMENT_COUNTER } from "../Constants";

// 直接将默认state设为0,对应counter的初始值
const counterReducer = (state = 0, action) => {
    switch (action.type) {
        case INCREMENT_COUNTER:
            return state + 1
        
        case DECREMENT_COUNTER:
            return state - 1

        default:
            return state
    }
}

export default counterReducer

优化App组件(可选)

直接在useSelector中获取需要的counter值,避免冗余:

import React from 'react';
import './App.css';
import { useDispatch, useSelector } from 'react-redux';
import { decrementCounter, incrementCounter } from './actions/counter.action';

function App() {
  // 直接获取counter数值
  const counter = useSelector(state => state.counter)
  const dispatch = useDispatch()
  
  return (
    <div>
      <h1>Counter: {counter}</h1>
      <button onClick={() => dispatch(incrementCounter())}>Increment</button>
      <button onClick={() => dispatch(decrementCounter())}>Decrement</button>
    </div>
  );
}

export default App;

修改后:

  • store的state结构为{counter: 0},点击按钮后数值会正常增减
  • 渲染时传入的是数字类型,不会触发React子元素错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 06:23:18