"Actions must be plain objects. Use custom middleware for async actions." 和 react/redux
"Actions must be plain objects. Use custom middleware for async actions." with react/redux
我遇到了这个错误,并花了最后几个小时试图解决这个问题。我查看了所有看似重复的问题 - 但它们并没有解决问题。
在我的 react/redux 应用程序中,当我在我的一个操作中发出 ajax 请求时,它会抛出此错误:
Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
我创建的商店如下所示:
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(
applyMiddleware(thunkMiddleware)
));
相关的reducer是这样的:
import * as actions from './../../actions/tools/vehicle-lookup';
const defaultState = {
vrm: void 0,
isLoading: false,
response: void 0,
error: void 0,
};
export default function (state = defaultState, action) {
switch (action.type) {
case actions.VEHICLE_LOOKUP:
return { ...state, isLoading: true, vrm: action.vrm };
case actions.VEHICLE_LOOKUP_SUCCESS:
return { ...state, isLoading: false, payload: action.payload, error: void 0 };
case actions.VEHICLE_LOOKUP_FAILURE:
return { ...state, isLoading: false, error: action.error, response: void 0 };
default: return state;
}
}
相关操作如下所示:
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) {
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)));
};
}
function requestVehicleLookup() {
return { type: VEHICLE_LOOKUP };
}
function receiveVehicleData(payload: object) {
return { type: VEHICLE_LOOKUP_SUCCESS, payload };
}
function receiveVehicleDataFailure(error: object) {
return { type: VEHICLE_LOOKUP_FAILURE, error };
}
我的包版本是:
"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",
第一个想法是你的 fetchVehicleLookup
动作很糟糕,因为你要返回 axios
而不是在内部调度。
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)));
};
}
只需删除您操作中的 return
语句,因为它会返回 axios 表示的任何对象,我想这将是某种形式的 Promise
.
第二个想法可能与您的商店设置有关,因为听起来 thunk
实际上并没有发挥作用。
我设法弄明白了 - 在与@Glitch100 聊了很长时间之后(谢谢!)。我需要 return 在创建 axios 承诺后立即调度 requestVehicleLookup。像这样:
export function fetchVehicleLookup(vrm: string, jwt: string) {
return function (dispatch) {
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)));
return dispatch(requestVehicleLookup());
};
}
我遇到了这个错误,并花了最后几个小时试图解决这个问题。我查看了所有看似重复的问题 - 但它们并没有解决问题。
在我的 react/redux 应用程序中,当我在我的一个操作中发出 ajax 请求时,它会抛出此错误:
Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
我创建的商店如下所示:
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(
applyMiddleware(thunkMiddleware)
));
相关的reducer是这样的:
import * as actions from './../../actions/tools/vehicle-lookup';
const defaultState = {
vrm: void 0,
isLoading: false,
response: void 0,
error: void 0,
};
export default function (state = defaultState, action) {
switch (action.type) {
case actions.VEHICLE_LOOKUP:
return { ...state, isLoading: true, vrm: action.vrm };
case actions.VEHICLE_LOOKUP_SUCCESS:
return { ...state, isLoading: false, payload: action.payload, error: void 0 };
case actions.VEHICLE_LOOKUP_FAILURE:
return { ...state, isLoading: false, error: action.error, response: void 0 };
default: return state;
}
}
相关操作如下所示:
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) {
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)));
};
}
function requestVehicleLookup() {
return { type: VEHICLE_LOOKUP };
}
function receiveVehicleData(payload: object) {
return { type: VEHICLE_LOOKUP_SUCCESS, payload };
}
function receiveVehicleDataFailure(error: object) {
return { type: VEHICLE_LOOKUP_FAILURE, error };
}
我的包版本是:
"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",
第一个想法是你的 fetchVehicleLookup
动作很糟糕,因为你要返回 axios
而不是在内部调度。
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)));
};
}
只需删除您操作中的 return
语句,因为它会返回 axios 表示的任何对象,我想这将是某种形式的 Promise
.
第二个想法可能与您的商店设置有关,因为听起来 thunk
实际上并没有发挥作用。
我设法弄明白了 - 在与@Glitch100 聊了很长时间之后(谢谢!)。我需要 return 在创建 axios 承诺后立即调度 requestVehicleLookup。像这样:
export function fetchVehicleLookup(vrm: string, jwt: string) {
return function (dispatch) {
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)));
return dispatch(requestVehicleLookup());
};
}