2017-02-14 25 views
2

Я пишу специальное промежуточное программное обеспечение, которое должно отправлять действия thunk. Проблема в том, что промежуточное ПО вызывается после redux-thunk в цепочке промежуточного программного обеспечения, поэтому я получаю ошибку Uncaught Error: Actions must be plain objects. Use custom middleware for async actions. при использовании предоставленного dispatch.Пользовательское промежуточное ПО Redux - отправка в начало сети промежуточного программного обеспечения?

export default function createMiddleware() { 
    return ({dispatch, getState}) => next => (action) => { 
     if(action.type !== 'FOO') { 
      return next(action); 
     } 

     dispatch(thunkActionHere); // this is the issue 
    } 
} 

Я хотел бы направить этот стук действие назад к началу промежуточного слоя цепи, так что перевождь-преобразователь может обрабатывать его. Это возможно?

обновление:

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-стук, потому что тогда он не получает действия, санки отправки.

ответ

1

Оказалось, проблема была в моей конфигурации магазина. Эта проблема вызвала отказ 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)); 
} 
3

Отправка внутри цепи промежуточного программного обеспечения отправит действие в начало цепи промежуточного программного обеспечения и вызовет вызов как обычно (Demo - посмотрите на консоль).

Почему?

оригинальный store.dispatch() (перед нанесением промежуточное программное) проверяет, является ли действие простой POJO, а если не выдает ошибку:

function dispatch(action) { 
    if (!isPlainObject(action)) { 
     throw new Error(
     'Actions must be plain objects. ' + 
     'Use custom middleware for async actions.' 
    ) 
    } 

При applyMiddleware()dispatch заменяется новым методом, который цепочка промежуточного программного обеспечения, которая в конце концов вызывает оригинал store.dispatch(). Вы можете увидеть его в методе applyMiddleware:

export default function applyMiddleware(...middlewares) { 
    return (createStore) => (reducer, preloadedState, enhancer) => { 
    const store = createStore(reducer, preloadedState, enhancer) 
    let dispatch = store.dispatch // dispatch is now the original store's dispatch 
    let chain = [] 

    const middlewareAPI = { 
     getState: store.getState, 
     dispatch: (action) => dispatch(action) // this refers to the dispatch variable. However, it's not the original dispatch, but the one that was created by compose 
    } 
    chain = middlewares.map(middleware => middleware(middlewareAPI)) 
    dispatch = compose(...chain)(store.dispatch) // dispatch is a composition of the chain, with the original dispatch in the end 

    return { 
     ...store, 
     dispatch 
    } 
    } 
} 

кстати - изменить связующее ПО это, так как первая функция позволит предотвратить промежуточное программное обеспечение от работы.

export default const createMiddleware = ({dispatch, getState}) => next => (action) => { 
    if(action.type !== 'FOO') { 
     return next(action); 
    } 

    dispatch(thunkActionHere); // this is the issue 
} 
+0

Оказывается, проблема была в моей конфигурации магазина. Эта проблема вызвала использование 'compose' от redux. –

+1

Можете ли вы добавить его в качестве другого ответа? Это интересно. –

+0

уверенный вещь, только сделал –

 Смежные вопросы

  • Нет связанных вопросов^_^