React与Redux中Actions must be plain objects错误求助
解决Redux异步Action报错:Actions must be plain objects. Use custom middleware for async actions.
这个错误的核心原因很明确:Redux默认只能处理普通JavaScript对象(plain object)类型的Action,而你写的setNotification返回的是一个接收dispatch参数的函数——这是异步Action的写法,需要借助中间件才能让Redux识别并处理它。
具体解决步骤:
安装并配置Redux Thunk中间件
Thunk是Redux官方推荐的处理异步Action的中间件,它允许你的Action Creator返回函数而非普通对象。- 首先安装依赖:
npm install redux-thunk # 或者用yarn yarn add redux-thunk - 然后在创建Redux Store的时候,把Thunk添加到中间件链中:
如果是传统Redux(不用Redux Toolkit):
如果你用Redux Toolkit(更推荐的现代写法),import { createStore, combineReducers, applyMiddleware } from 'redux' import thunk from 'redux-thunk' import notificationReducer from './reducers/notificationReducer' // 假设你还有其他reducer,比如anecdoteReducer import anecdoteReducer from './reducers/anecdoteReducer' const rootReducer = combineReducers({ notification: notificationReducer, anecdotes: anecdoteReducer }) const store = createStore(rootReducer, applyMiddleware(thunk))configureStore默认已经集成了Thunk,只需要正常配置即可:import { configureStore } from '@reduxjs/toolkit' import notificationReducer from './reducers/notificationReducer' import anecdoteReducer from './reducers/anecdoteReducer' const store = configureStore({ reducer: { notification: notificationReducer, anecdotes: anecdoteReducer } })
- 首先安装依赖:
修正Action Creator中的数据字段
你的setNotification里的dispatch语句有个小问题:当前你dispatch的是{ type: "SET_NOTIFICATION", content },但你的reducer里是通过action.data来获取内容的,这会导致reducer拿不到正确的数据。需要把content放到data字段里:
export const setNotification = (content, seconds) => { return dispatch => { dispatch({ type: "SET_NOTIFICATION", data: content }); // 这里改成data: content setTimeout(() => { dispatch({ type: "REMOVE_NOTIFICATION" }); }, seconds * 1000); }; };
- 简化不必要的异步Action Creator
你的removeNotification只是同步dispatch一个Action,完全不需要写成返回函数的形式,可以改成普通的同步Action Creator:
export const removeNotification = () => { return { type: "REMOVE_NOTIFICATION" }; };
验证效果
完成以上配置后,当你点击按钮触发voteHandler时,Redux Thunk会自动处理setNotification返回的函数:先立即dispatchSET_NOTIFICATION更新通知状态,等待指定秒数后再dispatchREMOVE_NOTIFICATION清除通知,错误就会消失,功能也能正常工作了。
内容的提问来源于stack exchange,提问作者John Rogerson
相关产品推荐
相关产品推荐

