2017-04-10 4 views
4

J'ai rencontré cette erreur et j'ai passé les dernières heures à essayer de comprendre. J'ai regardé toutes les questions qui semblent être des doublons - mais elles ne résolvent pas le problème."Les actions doivent être des objets simples Utilisez un middleware personnalisé pour les actions asynchrones." with react/redux

Dans ma réaction app/Redux, quand je fait une demande ajax dans un de mes actions, il jette cette erreur sur: Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.

Ma création de magasin ressemble à ceci:

import { composeWithDevTools } from 'redux-devtools-extension'; 
 
import reducers from './reducers'; 
 
import thunkMiddleware from 'redux-thunk'; 
 
import { applyMiddleware, createStore } from 'redux'; 
 

 
export default createStore(reducers, composeWithDevTools(
 
\t applyMiddleware(thunkMiddleware) 
 
));

Le réducteur concerné ressemble à ceci:

import * as actions from './../../actions/tools/vehicle-lookup'; 
 

 
const defaultState = { 
 
\t vrm: void 0, 
 
\t isLoading: false, 
 
\t response: void 0, 
 
\t error: void 0, 
 
}; 
 

 
export default function (state = defaultState, action) { 
 
\t switch (action.type) { 
 
\t \t case actions.VEHICLE_LOOKUP: 
 
\t \t \t return { ...state, isLoading: true, vrm: action.vrm }; 
 

 
\t \t case actions.VEHICLE_LOOKUP_SUCCESS: 
 
\t \t \t return { ...state, isLoading: false, payload: action.payload, error: void 0 }; 
 

 
\t \t case actions.VEHICLE_LOOKUP_FAILURE: 
 
\t \t \t return { ...state, isLoading: false, error: action.error, response: void 0 }; 
 

 
\t \t default: return state; 
 
\t } 
 
}

L'action concernée ressemble à ceci:

import axios from 'axios'; 
 

 
export const VEHICLE_LOOKUP = 'VEHICLE_LOOKUP'; 
 
export const VEHICLE_LOOKUP_SUCCESS = 'VEHICLE_LOOKUP_SUCCESS'; 
 
export const VEHICLE_LOOKUP_FAILURE = 'VEHICLE_LOOKUP_FAILURE'; 
 

 
export function fetchVehicleLookup(vrm: string, jwt: string) { 
 
\t return function (dispatch) { 
 
\t \t dispatch(requestVehicleLookup()); 
 

 
\t \t axios.create({ 
 
\t \t \t timeout: 4000, 
 
\t \t }) 
 
\t \t \t .post('/*api url*', { 
 
\t \t \t \t action: '*method*', 
 
\t \t \t \t body: { vrm }, 
 
\t \t \t }) 
 
\t \t \t .then(response => response.data) 
 
\t \t \t .then(json => dispatch(receiveVehicleData(json))) 
 
\t \t \t .catch(error => dispatch(receiveVehicleDataFailure(error))); 
 
\t }; 
 
} 
 

 
function requestVehicleLookup() { 
 
\t return { type: VEHICLE_LOOKUP }; 
 
} 
 

 
function receiveVehicleData(payload: object) { 
 
\t return { type: VEHICLE_LOOKUP_SUCCESS, payload }; 
 
} 
 

 
function receiveVehicleDataFailure(error: object) { 
 
\t return { type: VEHICLE_LOOKUP_FAILURE, error }; 
 
}

Mes versions package sont:

"axios": "^0.16.0", 
"react": "^15.4.2", 
"react-addons-css-transition-group": "^15.5.0", 
"react-addons-transition-group": "^15.5.0", 
"react-dom": "^15.4.2", 
"react-hot-loader": "^3.0.0-beta.6", 
"react-redux": "^5.0.3", 
"react-router": "^4.0.0", 
"react-router-dom": "^4.0.0", 
"redux": "^3.6.0", 
"redux-devtools-extension": "^2.13.0", 
"redux-promise": "^0.5.3", 
"redux-promise-middleware": "^4.2.0", 
"redux-thunk": "^2.2.0", 
+0

Pouvez-vous inclure également le code où votre action async est en cours d'expédition? – Samo

Répondre

-1

J'ai réussi à comprendre - après un très long chat avec @ Glitch100 (merci!). J'avais besoin de renvoyer l'envoi de requestVehicleLookup juste après la création de la promesse axios. Comme si:

export function fetchVehicleLookup(vrm: string, jwt: string) { 
 
\t return function (dispatch) { 
 
\t \t axios.create({ 
 
\t \t \t timeout: 4000, 
 
\t \t }) 
 
\t \t \t .post('/*api url*', { 
 
\t \t \t \t action: '*method*', 
 
\t \t \t \t body: { vrm }, 
 
\t \t \t }) 
 
\t \t \t .then(response => response.data) 
 
\t \t \t .then(json => dispatch(receiveVehicleData(json))) 
 
\t \t \t .catch(error => dispatch(receiveVehicleDataFailure(error))); 
 
     
 
     
 
\t \t return dispatch(requestVehicleLookup()); 
 
\t }; 
 
}

3

d'abord pensé que votre fetchVehicleLookup l'action gémissait parce que vous renvoyez le axios au lieu de simplement envoyer à l'intérieur.

export function fetchVehicleLookup(vrm: string, jwt: string) { 
    return function (dispatch) { 
     dispatch(requestVehicleLookup()); 

     axios.create({ 
      timeout: 4000, 
     }) 
      .post('/*api url*', { 
       action: '*method*', 
       body: { vrm }, 
      }) 
      .then(response => response.data) 
      .then(json => dispatch(receiveVehicleData(json))) 
      .catch(error => dispatch(receiveVehicleDataFailure(error))); 
    }; 
} 

Retirez simplement la déclaration return qui est dans votre action, comme il est de retour tout Axios objet représente, que j'imagine va être une certaine forme de Promise.

La deuxième réflexion pourrait être quelque chose autour de la configuration de votre magasin car il semble que thunk ne fonctionne pas réellement.

+0

J'ai supprimé ce retour de axios, et la même erreur est toujours présente malheureusement - sera éditer pour retirer de mon op –

+0

Par souci de test, supprimez toute la section 'axios', et envoyez simplement une action factice à la place. L'erreur est-elle toujours présente? – JonE