我正在使用react-redux和redux-thunk实现异步动作创建器。但是,我收到以下错误消息:未捕获错误:操作必须是普通对象。使用自定义中间件进行异步操作。
我知道动作应该是普通的对象,而像thunk这样的中间件应该在没有的情况下处理这些情况。我已经阅读了几个教程并查看了每个 SO问题,但我仍然无法弄清楚我出错的地方。我是否错误地设置了thunk,或者我是否以错误的方式使用了动作创建者?这可能是webpack或其他什么错误吗?
下面我列出了我认为相关的代码段。如果需要其他信息,请告诉我。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Route } from 'react-router';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
import Layout from './components/Layout.js';
import OrderPage from './containers/order-page';
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
ReactDOM.render(
<Provider store={store}>
<App>
<Route exact path="/" component={Layout}/>
</App>
</Provider>,
document.querySelector('.app'));
减速器/ order.js
import { FETCH_ERR, FETCH_SUCCESS, START_FETCH } from '../actions/types';
const initialState = {
fetching: false
};
export default (state=initialState, action)=>{
switch (action.type) {
case START_FETCH:
return {
fetching: true
}
case FETCH_ERR:
return {
err: action.payload.err,
fetching: false
}
case FETCH_SUCCESS:
return {
price: action.payload,
fetching: false
}
default:
return state
}
}
操作/价格fetch.js
import axios from 'axios'
const FETCH_ERR = 'FETCH_ERR'
const FETCH_SUCCESS = 'FETCH_SUCCESS'
const START_FETCH = 'START_FETCH'
const fetchSucc = (data)=>{
return{
type:FETCH_SUCCESS,
payload:data
}
}
const fetchFail = (message)=>{
return{
type:FETCH_ERR,
payload:message
}
}
const startFetch = () =>{
return{
type: START_FETCH,
payload:null
}
}
const fetchPrices = () =>{
return async (dispatch) =>{
try {
dispatch(startFetch())
let data = await axios.get('mybackendurl')
dispatch(fetchSucc(data))
} catch (error) {
dispatch(fetchFail({err:'failed to get shit'}))
}
}
}
export {
FETCH_ERR,
FETCH_SUCCESS,
fetchPrices,
START_FETCH
}
相关容器/ order.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchPrices } from '../actions/price-fetch';
class Order extends Component {
...
render() {
this.props.fetchPrices();
return ...
}
const mapDispatchToProps = dispatch => {
return {
fetchPrice: () => {
dispatch(fetchPrices())
}
}
}
function mapStateToProps(state){
return {
prices: state.order
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Order);
提前感谢您的帮助!
答案 0 :(得分:1)
如果有人遇到同样的问题。问题不在上面显示的代码中,或者我是如何调度操作的。我在另一个文件中有一个重复的redux-store定义,它用中间件覆盖了定义。
答案 1 :(得分:1)
如果有人在使用ImmutableJS + Typescript时不知所措,那么您实际上必须为中间件实际应用定义“ initialState”。
export const store = createStore(
combineReducers({APIReducer}),
{},
applyMiddleware(thunk.withExtraArgument(api))
);
答案 2 :(得分:0)
我怀疑这可能是因为你有一个async (dispatch)
功能。这会导致它返回Promise
,这可能会让thunk
感到困惑。
在正常情况下,函数本身会返回另一个函数,thunk
将注入dispatch
并再次调用,您将在函数内调用dispatch
:
arg => dispatch => dispatch({ type: arg });
当您添加async
时,它基本上与此相同:
arg => dispatch => Promise.resolve(dispatch({ type: arg }));
您可能不得不放弃async/await
内部axios
作为普通Promise
,或者添加额外内容以确保它不返回任何内容Promise
}。
答案 3 :(得分:0)
const mapDispatchToProps = dispatch => {
return {
fetchPrice: () => {
dispatch(fetchPrices())
}
}
}
当你做时,会返回一个承诺
dispatch(fetchPrices())
const mapDispatchToProps = dispatch => {
return {
fetchPrice
}
}
承诺不是普通对象
#team1Cont {
transform: rotate(180deg);
}
你可以这样表明&#34;加载请等待&#34;而价格表是空的,承诺没有得到解决/拒绝