使用Redux Thunk异步中间件分发Action报错的排查与解决
解决Redux Thunk异步Action报错:Error: Actions must be plain objects. Use custom middleware for async actions.
问题描述
你在使用Redux Thunk处理异步Action时遇到了上述错误,你的异步Action已经按照Thunk要求写成了返回函数的形式,但控制台依然抛出错误。相关代码如下:
Store配置代码:
import React from 'react'; import ReactDOM from 'react-dom'; import 'babel-polyfill'; import ReduxThunk from 'redux-thunk'; import { createStore, combineReducers,applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; import { Router, Route, IndexRoute, browserHistory } from 'react-router'; import { syncHistoryWithStore, routerReducer } from 'react-router-redux'; import App, { reducer } from './AppContainer'; import {launchReducer} from './modules/Financeiro/Lancamentos/reducer/launchReducer'; import {Rotas} from './routes'; // Add the reducer to your store on the `routing` key const store = createStore( combineReducers({ app: reducer, routing: routerReducer, launch: launchReducer }), applyMiddleware(ReduxThunk), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), ); // Create an enhanced history that syncs navigation events with the store const history = syncHistoryWithStore(browserHistory, store); document.getElementById('app').style['min-height'] = '100vh'; ReactDOM.render( <Provider store={store}> <Router history={history}> {Rotas.map(rota => ( <Route path={rota.path} component={App}> <IndexRoute component={rota.component} /> </Route>) )} </Router> </Provider>, document.getElementById('app') // eslint-disable-line comma-dangle );
异步Action代码:
export const newLaunch = (obj) => async (dispatch) => { delete obj.idLaunch_headerOrigin let resp = await APIService('http://localhost:3000/launch/newLaunch', obj, 'POST') dispatch({type: SET_LAUNCH_HEADER_ORIGIN, payload: resp.response}) }
你已经通过react-redux的connect将该Action连接到组件,并通过this.props.newLaunch(obj)调用。
问题原因
核心问题是**createStore的参数顺序错误**!createStore的参数定义是:createStore(reducer, preloadedState?, enhancer?)
第二个参数是预加载的state,第三个参数才是store增强器(比如中间件)。你把applyMiddleware(ReduxThunk)放在了第二个参数的位置,导致Redux没有正确识别并应用Thunk中间件,自然无法处理返回函数的异步Action,从而抛出错误。
解决方法
调整createStore的参数顺序,将预加载state(这里的DevTools扩展本质也是增强器)和中间件的位置调换,正确的store配置代码如下:
const store = createStore( combineReducers({ app: reducer, routing: routerReducer, launch: launchReducer }), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), applyMiddleware(ReduxThunk), );
如果想更规范地同时使用DevTools扩展和中间件,推荐使用compose来组合多个增强器,避免参数顺序混淆:
import { createStore, combineReducers, applyMiddleware, compose } from 'redux'; // 优先使用DevTools的compose,没有则用Redux自带的 const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( combineReducers({ app: reducer, routing: routerReducer, launch: launchReducer }), composeEnhancers( applyMiddleware(ReduxThunk) ) );
这种方式结构更清晰,也能确保中间件和DevTools扩展都能正常生效。
内容的提问来源于stack exchange,提问作者Caíque Carbone Gonçalves
相关产品推荐
相关产品推荐

