Redux Toolkit报错:Actions必须是纯对象,点击按钮状态未更新
问题解决方案
错误原因分析
1. Dispatch 使用方式错误
你在按钮的onClick中直接调用useDispatch(enterDigit('1')),这是错误的:
useDispatch是React Hook,用来获取dispatch函数,不能直接传入action对象作为参数- 这种写法会导致组件渲染时立即执行dispatch,而非点击按钮时执行,同时不符合Redux的动作分发规范,触发了"Actions must be plain objects"错误
2. Reducer 中状态更新逻辑错误
在enterDigit reducer里,当state.display不为0时,你执行了[ ...state.display ].concat(action.payload),但没有将结果赋值给state.display,导致display状态完全没有更新;另外初始state.display是数字类型,需要先转为字符串再进行拼接,避免数字相加的问题。
修正后的代码
1. App.js 修正
import { useSelector, useDispatch } from 'react-redux'; import { enterDigit, getDisplay } from './features/calculatorSlice'; const App = () => { const state = useSelector(state => state.calculator); // 先获取dispatch函数 const dispatch = useDispatch(); return ( <div className="container"> <div className="top-container"> <h1>{state.display}</h1> </div> <div className="bottom-container"> {/* onClick传入一个函数,点击时再分发动作 */} <button onClick={() => dispatch(enterDigit('1'))}>1</button> </div> </div> ); }; export default App;
2. calculatorSlice.js 修正
const initialState = { display: '0', // 初始改为字符串,避免后续类型转换问题 currentOperand: null, previousOperand: null, currentOperator: null }; export const calculatorSlice = createSlice({ name: 'calculator', initialState, reducers: { getDisplay (state) { return state.display; }, enterDigit (state, action) { if (state.display !== '0') { // 直接字符串拼接并赋值给state.display state.display += action.payload; } else { state.display = action.payload; } state.currentOperand = parseFloat(state.display); } } });
额外说明
- 将
initialState.display初始化为字符串'0',可以统一后续的拼接逻辑,避免数字与字符串混合操作的问题 - Redux Toolkit的createSlice已经内置了Immer,所以你可以直接修改state对象,不需要手动返回新状态(Immer会自动处理不可变更新)
内容的提问来源于stack exchange,提问作者Arshad Khan
相关产品推荐
相关产品推荐

