我正在编写一个需要调度重击动作的自定义中间件。问题是中间件redux-thunk在中间件链中被调用,所以Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.在使用提供的时出现错误dispatch。
redux-thunk
Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
dispatch
export default function createMiddleware() { return ({dispatch, getState}) => next => (action) => { if(action.type !== 'FOO') { return next(action); } dispatch(thunkActionHere); // this is the issue } }
我想将此重击操作分派回中间件链的开头,以便redux-thunk可以处理它。这可能吗?
更新:
function createMiddleware(extraArgument) { return function ({dispatch, getState}) { return function (next) { return function (action) { switch (action.type) { case 'FOO1': dispatch({type: 'NORMAL_ACTION'}); // works fine break; case 'FOO2': dispatch(function() { return (dispatch, getState) => { // Error: Actions must be plain objects. Use custom middleware for async actions. console.log('inside the thunk'); }; }); break; default: return next(action); } }; }; }; } const middleware = createMiddleware(); middleware.withExtraArgument = createMiddleware; export default middleware;
这是我的商店配置:
export default function configureStore(initialState) { const store = createStore(rootReducer, initialState, compose( // Add other middleware on this line... applyMiddleware(bugsnagErrorCatcherMiddleware()), applyMiddleware(thunk.withExtraArgument({APIFactory, PusherManager})), applyMiddleware(webrtcVideoMiddleware.withExtraArgument(PusherManager)), // this is the middleware above applyMiddleware(bugsnagbreadcrumbLoggerMiddleware()), ) ); return store; }
我不能将中间件放在redux-thunk之前,因为那样的话,它就不会收到thunk调度的动作。
原来问题出在我的商店配置中。使用redux compose引起了问题。
compose
之前:
import {createStore, applyMiddleware, compose} from 'redux'; import thunk from 'redux-thunk'; import rootReducer from '../redux/reducers'; import webrtcVideoMiddleware from '../redux/middleware/webrtcVideo'; import bugsnagErrorCatcherMiddleware from '../redux/middleware/bugsnag/errorCatcher'; import bugsnagbreadcrumbLoggerMiddleware from '../redux/middleware/bugsnag/breadcrumbLogger'; import * as APIFactory from '../services/APIFactory'; import Pusher from '../services/PusherManager'; const PusherManager = new Pusher(false); export default function configureStore(initialState) { return createStore(rootReducer, initialState, compose( applyMiddleware(bugsnagErrorCatcherMiddleware()), applyMiddleware(thunk.withExtraArgument({APIFactory, PusherManager})), applyMiddleware(webrtcVideoMiddleware(PusherManager)), applyMiddleware(bugsnagbreadcrumbLoggerMiddleware()) )); }
后:
import {createStore, applyMiddleware} from 'redux'; import thunk from 'redux-thunk'; import rootReducer from '../redux/reducers'; import webRTCVideoMiddleware from '../redux/middleware/webrtcVideo'; import bugsnagErrorCatcherMiddleware from '../redux/middleware/bugsnag/errorCatcher'; import bugsnagBreadcrumbLoggerMiddleware from '../redux/middleware/bugsnag/breadcrumbLogger'; import * as APIFactory from '../services/APIFactory'; import Pusher from '../services/PusherManager'; const PusherManager = new Pusher(false); export default function configureStore(initialState) { const middleware = [ bugsnagErrorCatcherMiddleware(), thunk.withExtraArgument({APIFactory, PusherManager}), webRTCVideoMiddleware.withExtraArgument(PusherManager), bugsnagBreadcrumbLoggerMiddleware(), ]; return createStore(rootReducer, initialState, applyMiddleware(...middleware)); }